mysql 数据丢失更新的解决方法
问题描述:
mysql 数据库丢失更新的定义:(其实在数据库角度都不会产生丢失更新的问题,问题的源头应用程序逻辑更新的问题)
1. 事务1 查询一行数据放在本地缓存,并且显示给用户user1 -->select balance from account where user= 'a' ;
2. 事务2 查询同样的一行数据放在本地缓存,并且显示给用户user2 -->select balance from account where user= 'a' ;
3. 用户user1修改这条数据,并且更新提交数据库 --> update account set balance = balance -100 where user= 'a' ;
4. 用户user2修改显示的数据,并且更新提交数据库 --> update account set balance = balance -800 where user= 'a' ;
显然上面user1 更新的数据丢失了,这也是更新覆盖,比如用户转账的操作。a 账户总共1000,事务1和事务2查询账户都是1000,然后事务1账户扣减100,提交。事务2扣减800提交。这时候账户余额为200,事务1扣减的100 会不翼而飞,实际上应该剩下100,这会导致严重的问题。
-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
暂时想到两种解决办法:
解决办法1:使用悲观锁
1)读取锁定 --> select balance from account where user= 'a' for update
2)更新 --> update account set balance = balance -100 where user= 'a'
解决办法2: 使用乐观锁
1)表增加字段 jpa_version int 版本号 --> select balance,version from account where user= 'a'
2) 使用版本号更新 --> update account set balance = balance -100 where user= 'a' and jpa_version = ${version}
解决办法3:
1) 验证未修改前的金额是否一致--> update account set balance = 100 where user= 'a' and balance = $old_balance
总结:
对于账户交易建议直接使用悲观,数据库的性能很高,并发度不是很高的场景两者性能没有太大差别。如果是交易减库存的操作可以考虑乐观锁,保证并发度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2019-06-11 谷歌Chrome浏览器 截取网页长图方法