当前位置:网站首页>两类更新丢失及解决办法
两类更新丢失及解决办法
2022-07-07 14:21:00 【fastjson_】
我们首先创建一张user表,id为主键
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`money` int DEFAULT NULL,
`version` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
第一类丢失更新(回滚丢失)
A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来:
时间 | 取款事务A | 转账事务B |
T1 | begin; |
|
T2 | begin; 开始事务 | |
T3 | select money from user where id = 1; | |
T4 | select money from user where id = 1; | |
T5 | money = 1000 + 100; | |
T6 | commit; | |
T7 | money = 1000 - 100; | |
T8 | rollback; | |
T9 | 余额恢复为1000 元(丢失更新) |
A事务在回滚时,“不小心”将B事务已经转入账户的金额给抹去了。
在MySQL数据库,任何隔离级别不允许第一类更新丢失
第二类丢失更新(覆盖丢失/两次更新问题)
A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失:
时间 | 转账事务A | 取款事务B |
T1 | begin; | begin; |
T2 | select money from user where id = 1; | |
T3 | select money from user where id = 1; |
|
T4 | money = 1000 + 100; update user set money=1100 where id = 1; 汇入100元 | |
T5 | commit; | |
T6 | select money from user where id = 1; |
|
T7 | money = 1000 - 100; update user set money=900 where id = 1; 取出100元把余额改为900元 | |
T8 | commit; | |
T9 | 把余额改为900 元(丢失更新) |
上面的例子里由于取款覆盖了转账对存款余额所做的更新,导致用户最后损失了100元,相反如果取款事务先提交,那么用银行将损失100元。
第二类丢失更新原因:MySQL可重复读默认采用的是快照读。快照读的一个问题也就是没有办法获取最新的数据。所以快照读是第二类更新丢失的一个主要原因。
解决快照读:基本两种思路,一种是悲观锁,另外一种是乐观锁;
简单的说就是一种假定这样的问题是高概率的,最好一开始就锁住,免得更新老是失败;另外一种假定这样的问题是小概率的,最后一步做更新的时候再锁住,免得锁住时间太长影响其他人做有关操作。
悲观锁
读取数据的时候加锁,这样能够保证读到的数据都是最新的数据,并且会将记录锁住,其他事物如果想要获取锁会阻塞。所以整体业务流程变成:在开启事物后要获取锁,然后根据业务场景不同进行不同操作
begin; 开启事务 | begin; 开启事务 |
select money from user where id = 1 for update; 查询账户余额为1000元 | |
select money from user where id = 1 for update; 阻塞... | |
money = 1000 - 100; update user set money=900 where id = 1; 取出100元把余额改为900元 | 阻塞... |
commit; | 阻塞... |
查到数据 :money = 900 | |
其他操作.... |
乐观锁
添加version字段,记录每条记录的更新版本,每次更新后版本号加一。
在每次事物开启之前获取行的版本号,在更新的时候带上版本号进行判断。update money set money = money + 100 where id = 1 and version = 查到的版本号
select version from user where id = 1; | |
select version from user where id = 1; | |
begin; | begin; |
money = 1000 - 100; | |
更新成功,更新条数为1 | money = 1000 + 100; update user set money=1100,version = version +1 where id = 1 and version = 0; 阻塞... |
阻塞... | |
commit | |
更新成功,更新条数为0(因为另一个事物修改了版本号现在版本号为1) |
总结:
悲观锁b方法是通过select..for update方式,这个可能会导致其他会话的阻塞,而乐观锁b方法需要多一个版本列的维护。
个人建议:在用户并发数比较少且冲突比较严重的应用系统中选择悲观锁方法,其他情况首先乐观锁版本列法。
边栏推荐
- Excessive dependence on subsidies, difficult collection of key customers, and how strong is the potential to reach the dream of "the first share of domestic databases"?
- 分类模型评价标准(performance measure)
- laravel构造函数和中间件执行顺序问题
- Xcode Revoke certificate
- Leetcode-136- number that appears only once (solve with XOR)
- Opencv configuration 2019vs
- How to implement backspace in shell
- Lecturer solicitation order | Apache seatunnel (cultivating) meetup sharing guests are in hot Recruitment!
- 【DesignMode】享元模式(Flyweight Pattern)
- What else can an ordinary person do besides working in a factory to make money?
猜你喜欢
3000 words speak through HTTP cache
95. (cesium chapter) cesium dynamic monomer-3d building (building)
AutoLISP series (1): function function 1
Logback logging framework third-party jar package is available for free
删除 console 语句引发的惨案
Vs tool word highlight with margin
2022 the 4th China (Jinan) International Smart elderly care industry exhibition, Shandong old age Expo
【Android -- 数据存储】使用 SQLite 存储数据
Imitate the choice of enterprise wechat conference room
Personal notes of graphics (1)
随机推荐
URL和URI的关系
Odoo集成Plausible埋码监控平台
删除 console 语句引发的惨案
PHP has its own filtering and escape functions
网关Gateway的介绍与使用
Leetcode-136- number that appears only once (solve with XOR)
Continuous creation depends on it!
Unity3d click events added to 3D objects in the scene
How does laravel run composer dump autoload without emptying the classmap mapping relationship?
AutoLISP series (3): function function 3
Description of vs common shortcut keys
laravel 是怎么做到运行 composer dump-autoload 不清空 classmap 映射关系的呢?
Shandong old age Expo, 2022 China smart elderly care exhibition, smart elderly care and aging technology exhibition
Laravel5.1 Routing - routing packets
[hcsd celebrity live broadcast] teach the interview tips of big companies in person - brief notes
Apache Doris just "graduated": why should we pay attention to this kind of SQL data warehouse?
【HCSD大咖直播】亲授大厂面试秘诀-简要笔记
AutoLISP series (1): function function 1
【Vulnhub靶场】THALES:1
three. JS create cool snow effect