第二类丢失更新 (覆盖丢失):
A 和 B 查询同样的记录,进行 “读取、计算、更新”,即各自 基于最初查询的结果 (非必须) 更新记录并提交,后提交的数据将覆盖先提交的,导致最终数据错误。
并发进行自增 / 自减是发生覆盖丢失的一个典型场景:
其中一个事务的更新被另外一个覆盖了。
以下是本人的操作:
两个session所用到的表:
以下是两个session的操作:
问题:
1.本人设置的隔离级别为read-uncommitted,这个隔离级别应该不能防止第二类更新丢失,可是上面的实验能否可以说明read-uncommitted可以做到防止第二类更新?
2.假如本人想测试第二类更新怎么样操作? 也就是说怎么样去实现第二类更新丢失?
3.隔离级别的底层能否是用锁实现的? 既然有了隔离级别,为什么还要锁的存在? 或既然有了锁的存在,为什么还要隔离级别?
A 和 B 查询同样的记录,进行 “读取、计算、更新”,即各自 基于最初查询的结果 (非必须) 更新记录并提交,后提交的数据将覆盖先提交的,导致最终数据错误。
并发进行自增 / 自减是发生覆盖丢失的一个典型场景:
其中一个事务的更新被另外一个覆盖了。
以下是本人的操作:
两个session所用到的表:
以下是两个session的操作:
问题:
1.本人设置的隔离级别为read-uncommitted,这个隔离级别应该不能防止第二类更新丢失,可是上面的实验能否可以说明read-uncommitted可以做到防止第二类更新?
2.假如本人想测试第二类更新怎么样操作? 也就是说怎么样去实现第二类更新丢失?
3.隔离级别的底层能否是用锁实现的? 既然有了隔离级别,为什么还要锁的存在? 或既然有了锁的存在,为什么还要隔离级别?
解决方案
10
表面看,隔离级别是隔离级别,锁是锁,但实际上本质两者是关联的,所谓隔离级别是指锁定多上时间,何时释放锁
10
测试了一下, set @a1=() 的这种用法可能是做了特殊处理,这个是有锁的,持续到事务结束
用 select @a1:= 或 select …. into @a1 或是纯粹的 select , 都不会有被锁的问题
用 select @a1:= 或 select …. into @a1 或是纯粹的 select , 都不会有被锁的问题