繁体   English   中英

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

[英]Multiple threads update same row in database at a time how to maintain consistence

在我的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

这将迫使每个线程等到前一个线程提交后再读取计数器。

这是必要的,因为您有两个潜在的问题,第一个是读取竞争,第二个是写入锁定。 在大多数RDBMS中,写锁定会自动获得,但是除非在读取之前明确地采取了写锁定,否则两个线程一起将计数器增加一次 (因为这两个线程都在更新前读取了原始值)。

如果需要并行写入,则需要插入一个表,然后稍后实现聚合。 但是,那是一个更复杂的设计模式。

您的问题不是100%明确,但我想您正在寻找不同的锁定策略: http : //docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#locking

如果您正在使用具有序列生成器(Oracle,Postgres等)的数据库,则应考虑使用它们。 假设您始终在执行相同的增量值,并且一个线程增量一个,另一个线程增量两个,那么这应该是一个很好的解决方案。

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

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

方法1 ,这或多或少是最后更新Wins的情况。 它或多或少避免了乐观锁定(版本计数)。 如果您没有从T1到T2的依赖关系,或者为了设置状态PARSED而没有依赖关系。 这应该很好。

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

方法3行级DB锁这里的解决方案与方法2大致相同,只是对悲观锁的要求稍加修正。 主要区别在于,在这种情况下,它可能是READ锁,并且如果是PESSIMISTIC READ,则可能甚至无法从数据库读取数据来刷新它。

Aproach 4应用程序级同步有许多不同的同步方法。 一个示例是将所有更新实际安排在BlockingQueue或JMS队列中(如果您希望它是持久的),然后从单个线程推送所有更新。 为了使它形象化,T1和T2会将元素放入队列,并且只有一个T3线程读取操作并将其推送到数据库服务器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM