5
回答
乐观锁能解决丢失更新的问题吗

各位大神,请问乐观锁能解决并发更新时丢失更新的问题吗?

个人认为是解决不了的;

1,第一个线程,查询account表,字段:balance为100

2,第二个线程,查询account表,字段:balance为100

3,第一个线程给balance+100

4,第二个线程给balance-50

5,第二个线程更新

6,第一个线程更新

7,第二个commit

8,第一个commit

结果变为了200,

实际应该为150,。

各位大神,我这么理解对吗?


<无标签>
举报
初级屌丝
发帖于2年前 5回/383阅
共有5个答案 最后回答: 2年前

乐观锁不是这样来的:

按照你的步骤,第一个线程sql语句应该是update account set balance = balance + 100 where balance = 100;

第二个线程都更新成150了,第一个线程的语句当然不执行。


--- 共有 7 条评论 ---
初级屌丝回复 @catlover :恩,只要能解决这个丢失更新的问题就可以,对吧 2年前 回复
catlover回复 @初级屌丝 : 像你这样处理肯定可以满足大多数的业务要求,那这样两个线程都可以更新进去了。 2年前 回复
初级屌丝回复 @catlover : 第二个线程应该是更新不了的对吧,之后用异常捕获后,在进行新的查询,然后在更新就可以了 2年前 回复
catlover回复 @初级屌丝 : 要看你情况了,在你的例子中,如果你是想在第1个线程执行后balance=200的情况下,第2个线程再更新成150,使用balance字段来当锁还是会丢失。 2年前 回复
初级屌丝回复 @catlover : 恩,刚才问了同事,你说的对。那么乐观锁是可以解决丢失更新的了? 2年前 回复
你这个明明没有加锁才会出现的问题吧,既然有乐观锁就不会丢失更新,乐观锁使用了cas这种机制,而且提供失败重试机制来保证数据的正确性,你可以看看AtomicInteger实现类
--- 共有 6 条评论 ---
ksfzhaohui回复 @初级屌丝 : 可以认为cas是对乐观锁的一种实现,你说的version也可以实现乐观锁 2年前 回复
ksfzhaohui回复 @初级屌丝 : compare and swap 比较并交换 2年前 回复
初级屌丝回复 @ksfzhaohui : 大神,话说cas机制是什么东东? 2年前 回复
初级屌丝回复 @ksfzhaohui : 恩,明白了~用version字段控制也是可以的。是可以解决这种丢失问题的对吧 2年前 回复
ksfzhaohui回复 @初级屌丝 :是没有加锁,但是每次在真正更新的时候会进行一次比较,发现balance已经不是之前的100了,所有回失败,进行下一次重试 2年前 回复

加一个字段:version 控制数据版本,每次修改版本都自增

如果一个进程(人)正在修改,读取出来的版本是1,然后提交的时候,发现版本号已产生变化(其他线程、人已修改过),那么就警告或者报错。

1.乐观锁可以解决丢失更新的问题。

2.你的理解是错的。

当第一个线程更新成功后,balance的值就变成了200,第二个线程再去用条件为balance=100去更新,会出现更新失败,返回行数0,这时候需要重新查询balance,再去进行更新,如果行数依旧返回0,那么再次去查询,再次更新,如此循环下去,直到成功为止。

--- 共有 1 条评论 ---
初级屌丝明白,我的想法有问题~应该是同一条数据同一时刻只能事务提交了下个事务才能操作 2年前 回复
顶部