Mysql乐观锁自旋一直不成功的问题

Mysql乐观锁自旋一直不成功的问题

场景

Mysql数据库,InnoDB引擎,事务级别可重复读。
表结构如下:

用比较ver实现乐观锁功能。代码大致逻辑是:
1、开启一个事务
2、查询test_table里id=1的数据,得到ver=2
3、处理业务逻辑
4、更新id=1这条数据的name为张四,ver=3,条件是ver=2,,id=1
5、如果更新失败,重复第2、3、4步。

问题

只要出现更新失败,就会一直2、3、4步不成功。

原因

执行第2步之后,id=1的数据被另一个事务将ver更新为3了。因为事务级别可重复读下,select采取的是快照读,update是当前读,所以select 查到的数据一直是当前事务开启时的快照(即ver=2,,但实际ver=3),update时,是当前读,条件ver=2当然会不成功。

示例

先开启一个事务A,执行:begin;
select name,ver from test_table where id =1;此时结果如下所示。
在这里插入图片描述
这时,执行另一个事务B:
begin;
update test_table set ver = 3 where id = 1;
commit;
在这里插入图片描述
再执行第一个事务中的update语句,显示实际更新行数0:
在这里插入图片描述
此时,我们另打开一个窗口,查id=1的这条数据,结果如下:
在这里插入图片描述
ver=3,。这时,事务A还没有提交,我们在事务A中,再执行一次select语句,结果如下:
在这里插入图片描述
得到的仍然是ver=2。

解决办法

将查询从事务中提出来或者将重试逻辑从事务中独立出来(即A调B,在A中重试,B中开启事务)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值