间隙锁
- 如果在查询的后面加上for update表示查询为当前读,而不是读快照,有可能会导致幻读的问题
- 问题重现:在一个事务a中锁住了name为5的数据,然后再事务a期间,另外一个事务b把另外一条数据的name修改为5,此时,事务a再读一次name为5的数据,数据多了一条,导致一个事务里面,前后读到的数据是不一致的,(当前读才会有幻读的问题)
- 只要在这事务里面修改或新增为当前被锁的数据,就会产生幻读
- 为了解决幻读,引入了间隙锁
- 间隙锁锁的是数据之间的间隙,也就是不能新增或删除
- 间隙锁和行锁合成next-key lock
- 间隙锁是前闭后开的区间,间隙锁是最小的加锁单位,查找过程访问到的对象才会被加锁
优化
- 给唯一性索引等值查询加锁的时候,next-key lock会退化成行锁
- 索引等值查询时,向右遍历最后一个值不满足等值条件时,next-key lock退化成间隙锁
- 一个bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止
- 在删除数据的时候,尽量加上limit,减少扫描行数,和锁的区间数
- 加锁的时候是先加的间隙锁,再加的行锁
可能有个问题,会造成死锁,
-
在事务a中开启间隙锁,然后事务b开启间隙锁,事务a做update操作被事务b间隙所阻塞,事务b做update操作被事务a间隙锁阻塞造成死锁,所以间隙锁会影响并发度
-
所以很多吧隔离级别设置为读提交,同时把binlog_format=row