记录一次并发导致的钱包金额不一致,后者覆盖前者

使用的是hibernate  JPA, mysql 5.6

假设    

       线程T1读取钱包金额为100

同时

       线程T2也读取钱包金额为100


T1  增加钱包金额10,  钱包金额=110;

T2  增加钱包金额5 ,   钱包金额=105;

此时 T1  update    数据库记录为110;

T2随后 update     此时会将T1修改的数据给覆盖 为 105;

问题就出现了,后者更新覆盖了前者的更新,理论应该是 后者(T2) 增加5 ,应该在前者(T1) 更新数据之后的结果上增加


解决过程:

     使用乐观锁:在钱包实体 增加

      @Version
      private int version;

     字段 记录当前数据版本号,每次更新钱包时 同时自增当前version字段,后者更新时会比较当version版本是否一致,如果一致则更新成功,如果不一致将抛出异常 这时我们要手动捕获异常org.hibernate.StaleObjectStateException  再cath 里将需要处理的过程重新处理一遍即可解决。


 附上别的解决方法:

     对于对财务系统等对数据可靠性,正确性高的系统,可以使用 更新 金额钱 通过当前线程对 钱包表(或其它)

   进行表锁:LOCK TABLES 表名 WRITE;

  注意:此时当前锁住的表只有当前线程可以执行读取、更新,别的线程过来读取、更新 只能等待当前线程释放表锁,

此时就可以在当前线程内执行完成更新钱包记录然后释放锁

  释放表锁:UNLOCK TABLES;

释放锁后等待线程就会执行。

  因为是表锁,所以性能上肯定会有一定的影响,按需选择

        




猜你喜欢

转载自blog.csdn.net/chengluchuang2753/article/details/80737763