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

使用的是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;

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

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

        




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值