数据库事务二阶段提交(更新丢失问题)问题复现和解决
数据库事务二阶段提交(更新丢失问题)问题复现和解决
数据埋点 t_amout
userId userName Amount
0001 张三 100
0002 李四 500
事务A业务:0001向0002转账30元,返回异常情况 1.余额不足 2.系统异常
事务A业务:0001向0002转账50元,返回异常情况 1.余额不足 2.系统异常
事务A:select * from t_amout where userId=0001; amount 100
事务B: select * from t_amout where userId=0001; amount 100
事务A: update t_amout set amount=100-30 where userId=0001;
update t_amout set amount=amount+30 where userId=0002;
commit;
事务B:update t_amout set amount=100-50 where userId=0001;
update t_amout set amount=amount+50 where userId=0002;
commit;
现象:0001目前还有50元
解决方案:
1:乐观锁自旋
给数据加一个版本号,事务A更新之后,事务B更新会失败.就会自旋一次,重新查找,重新更新.
这种同时转账情况还是较少,而且自旋几次对于用户来说还是无感知的.
2:悲观锁
事务A:select * from t_amout where userId=0001 for update; Mysql会一直阻塞 Oracle有一点改变,可以指定阻塞时间.
数据埋点 t_amout
userId userName Amount
0001 张三 100
0002 李四 500
事务A业务:0001向0002转账30元,返回异常情况 1.余额不足 2.系统异常
事务A业务:0001向0002转账50元,返回异常情况 1.余额不足 2.系统异常
事务A:select * from t_amout where userId=0001; amount 100
事务B: select * from t_amout where userId=0001; amount 100
事务A: update t_amout set amount=100-30 where userId=0001;
update t_amout set amount=amount+30 where userId=0002;
commit;
事务B:update t_amout set amount=100-50 where userId=0001;
update t_amout set amount=amount+50 where userId=0002;
commit;
现象:0001目前还有50元
解决方案:
1:乐观锁自旋
给数据加一个版本号,事务A更新之后,事务B更新会失败.就会自旋一次,重新查找,重新更新.
这种同时转账情况还是较少,而且自旋几次对于用户来说还是无感知的.
2:悲观锁
事务A:select * from t_amout where userId=0001 for update; Mysql会一直阻塞 Oracle有一点改变,可以指定阻塞时间.
----------------------------------------------------------------
本文来自博客园,作者:苏子墨,转载请注明原文链接:https://www.cnblogs.com/li-xiaotian/p/16602288.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix