并发事务带来的问题
针对 mysql InnoDB
| 编号 | 问题 | 描述 |
|---|---|---|
| 1 | 脏读 | |
| 2 | 不可重复读 | |
| 3 | 幻读 | |
| 4 | 丢失更新 | 两个事务同时修改1 条记录,事务 A 的修改覆盖事务 B 的修改。 |
丢失更新
| 事务 A | 事务 B | |
|---|---|---|
| begin; | ||
| int b = select money from t where id = 0;//b 开始是 1 | ||
| b = b+1; | ||
| update t set money = b where id =0; | ||
| begin; | ||
| int b = select money from t where id = 0;//这里读到是 1 | ||
| b = b+2; | ||
| commit;//b=2 | ||
| update t set money = b where id =0; | ||
| commit;//覆盖 A 事务的 2,变成了 3 |
InnoDB默认的隔离级别 可重复读 RR + next-key Lock 解决了上面的 1~3 的问题,那丢失更新的解决方法如下:
- 通过悲观锁,通过 select xxx for update 加 X 锁
- 通过乐观锁(CAS), 记录加多一个版本号,查询时记录下来,更新的时候做比较,不等于是重复执行