概念
同一个事务中,同一次查询,后面一次查询查到了第一次查询不存在的内容
《RR下正常情况都是一样的视图,只有当前读才会出现幻读》
innoDB解决幻读手段-间隙锁
因为mysql一般只能加行锁只能锁住行,新插入的记录都是在间隙中生成的,所以行锁没发控制新纪录
只有RR的隔离级别下才有间隙锁,rc是没有间隙锁的
间隙锁之间不冲突
举个例子,表中不存在记录c1=1的记录
-
session A 在10:10执行select * from t where c1 = 1 lock in share mode;
- session B 在10:11执行select * from t where c1 = 1 for update;
sessionB不会被sessionA block主,A和B都没有加上行锁,因为行不存在,但是都加了同一个间隙锁,两个不冲突。
间隙锁和间隙间插入数据冲突
间隙锁就是加在记录之间的锁,线程A获取了间隙锁GapLock1(假设对应上图的15~20),如果此时线程B插入17的记录,这个时候会被block住
next-key lock
行锁和间隙锁合称next-key lock,前开后闭(]
锁范围:锁表?锁行?
SQL1 : update t set c1 = ‘c1’ where c2 = 'c2';
c2是UK索引,锁c2这一行;c2是非UK索引,锁全表
如果是非uk索引 为啥锁全表
如果只是锁c2=‘c2’的记录,有别的事务插入或修改制造新的c2=c2记录,SQL1是在之前加锁的,无法锁住后续的记录,破坏了语义