多个线程一次在数据库中更新同一行,如何保持一致性



在我的Java应用程序中多线程一次更新同一行如何获得一致性结果?

例如

current row value count =0; 
thread 1 updating it to count+1=1;
thread 2 updating at the same time count+1=2
    but it should not happen like this 
    thread 1 updating it to count+1=1;
    thread 2 updating at the same time count+1=1;
    both threads should not catch the same value because both are running same time 

    how can we achieve this in jdbc  hibernate , database ??  

有两种可能的方法。

  • 您要么选择一个悲观的方法和锁定行,表甚至行范围。

  • 或您使用版本的实体(乐观锁定)。

也许您可以在这里找到更多信息:

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html

以这种方式增加计数器是很难同时管理的。您确实需要使用悲观的锁定来解决这个特殊的问题。

SELECT 1 FROM mytable WHERE x IS TRUE FOR UPDATE

这将迫使每个线程等到上一个读取柜台之前。

这是必要的,因为您有两个潜在的问题,第一个是 read race,第二个是 write 锁定。写锁在大多数RDBMS中会自动捕获,但是除非您在阅读之前明确将其取出,否则两个线程都会通过两个线程将计数器递增一次(因为两者都在更新之前读取原始值)。p>如果您需要并行写入,则需要插入 ,然后稍后对聚合物进行实现。

这是一个更复杂的设计模式。

您的问题并不清楚100%,但我想您正在寻找不同的锁定策略:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/hibernate_user_guide.html#锁定

如果您正在处理具有序列发生器(Oracle,Postgres,...)的DB,则应考虑使用这些。假设您一直在执行相同的增量值,并且不是一个线程通过一个线增加一个,那么这应该是一个很好的解决方案。

这是对此问题的详细答案:如何正确处理数据库中更新同一行的两个线程总结:

最大的问题是:这两个线程是否试图持续相同的数据?总结链接答案的内容。让我们命名两个线程T1和T2。有几个侵犯:

方法1 ,这或多或少是最后一次更新WINS 情况。它或多或少避免了乐观的锁定(版本计数)。如果您没有从T1到T2的依赖性或反向以设置状态解析。这应该很好。

Ablect 2乐观的锁定这就是您现在拥有的。解决方案是刷新数据并重新启动您的操作。

Ablect 3行级db锁此处的解决方案或多或少与在悲观的锁定的小校正的方法2中相同。主要区别在于,在这种情况下,它可能是一个读取锁,您甚至可能无法从数据库中读取数据以刷新它,以刷新它。

Ablect 4应用程序级别同步有许多不同的方法可以进行同步。一个示例是将所有更新实际上在Blockingqueue或JMS队列中(如果您希望持续)并从单个线程中推动所有更新。要对其进行可视化,T1和T2将将元素放在队列上,并且将有一个T3线程读取操作并将其推入数据库服务器。

最新更新