有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

共 (3) 个答案

  1. # 1 楼答案

    以这种方式递增计数器很难同时管理。你真的需要使用悲观锁来解决这个问题

    SELECT 1 FROM mytable WHERE x IS TRUE FOR UPDATE
    

    这将迫使每个线程在读取计数器之前等待上一个线程提交

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

    如果需要并行写入,那么需要插入一个表,然后在以后具体化一个聚合。不过,这是一种更复杂的设计模式

  2. # 3 楼答案

    以下是对这个问题的详细回答: How to properly handle two threads updating the same row in a database 总结一下:

    最大的问题是:两个线程是否试图持久化相同的数据?总结链接答案的内容。让我们把这两个线程命名为T1和T2。这里有几条建议:

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

    这就是你现在拥有的。解决方案是刷新数据并重新启动操作

    一个3行级别的DB锁这里的解决方案与方法2的解决方案大致相同,带有悲观锁造成的小修正。主要的区别是,在这种情况下,它可能是一个读锁,如果是悲观读,您甚至可能无法从数据库中读取数据以刷新它

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