代码之家  ›  专栏  ›  技术社区  ›  SingleShot

多线程安全的JDBC保存或更新

  •  1
  • SingleShot  · 技术社区  · 15 年前

    我们所看到的是,一小部分新工作岗位被两次添加到数据库中。我们很确定这是因为作业的初始状态很快就会被状态更新所跟踪——一个进程得到一个,另一个进程得到另一个。这两个进程都会检查作业是否是新的,并且由于尚未记录作业,因此都会为作业创建一个记录。

    编辑:对于那些说“架构”不健全的人,我同意,但我无权改变它。

    2 回复  |  直到 7 年前
        1
  •  4
  •   meriton    15 年前

    在JOB_ID上创建唯一约束,并在发生约束冲突异常时重试以保持状态。

    话虽如此,我认为您的体系结构是不健全的:如果两个进程从队列中提取消息,则不能保证它们会按队列顺序将消息写入数据库:一个使用者可能会稍微慢一点,一个数据包可能会被丢弃,…,导致另一个使用者先保留后面的消息,导致它们被早期状态覆盖。

    当然,最简单的方法是只有一个消费者。。。

        2
  •  0
  •   duffymo    15 年前

    JDBC连接不是线程安全的,因此对此没有什么可做的。

    “…两个相同的进程从队列中拉出来,通过JDBC保持状态…”

    我一点也不明白。为什么有两个相同的过程?拥有一个消息队列侦听器池不是更好吗?每个侦听器都可以处理登录到队列上的消息?每个侦听器都有自己的线程;每一个都是它自己的事务。JavaEE应用服务器允许您配置消息侦听器池的大小以匹配负载。

    我认为一个重复这样一个过程的设计是自找麻烦的。

    您还可以更改JDBC连接上的隔离级别。如果您使其可串行化,您将以较慢的性能为代价确保ACID。

    由于这是一个异步进程,只有当您发现侦听器无法跟上队列上的消息时,性能才会成为一个问题。如果是这种情况,您可以尝试增加侦听器池的大小,直到您有足够的容量来处理传入消息。