0

我正在编写一个 Java 应用程序来更新关系数据库(目前是 H2)。我有一个执行以下操作的过程:

  1. 查询特定数据项的外部系统
  2. 通过检查导入日志表来检查这些项目是否已经导入到我们的系统中。如果不:
  3. 将新数据项导入到各种表中。
  4. 将新记录写入导入日志表。

这个过程可能在不同的线程中同时运行。我想避免两个线程可能都检查导入日志,在那里找不到任何东西,然后都尝试插入数据项的问题。

什么可能是一个好方法?我一直在考虑:

  1. 使用 SERIALIZABLE 事务隔离。
  2. 依靠导入日志中的唯一索引约束来出错并回滚其中一个事务。
  3. 将进程限制为 Java 应用程序中的单个线程。

出于各种原因,以上所有方法似乎都不是很吸引人——还有另一种可能效果更好的方法吗?

4

2 回答 2

0

我会颠倒你的过程。我不会轮询源以获取更改,而是让您的源将更改写入队列(我想到了 JMS,但它可以是任何队列)。这将使您的工作更轻松,并且可能具有更好的性能。

在您的外部系统中执行此操作就像在数据库中添加一些触发器或在持久层中添加任何侦听器(如果有的话)一样简单,就像任何审计程序一样。

当然,只有当您可以控制源数据时,此选项才有意义。

为什么需要很多线程来进行同步?

于 2014-02-28T13:07:16.237 回答
0

SERIALIZABLE 事务隔离当然是实现目标的最确定的方法,但它可能意味着性能会受到影响。

您没有考虑过一种选择,那就是构建您自己的信号量。

您可以创建当前正在处理的项目的静态 ConcurrentHashMap 并且(在每个插入过程开始时 - 放置一条记录并在完成后将其删除。

然后每个线程进程可以在开始插入之前咨询这个信号量。

于 2014-02-28T13:50:51.123 回答