幻读
概念
一个事务中的两次同样的查询不一致。
解决幻读:
RR:使用select ... for update加排他锁
for update的引入是为了幂等性问题,如果不加for update可能出现并发问题。
【参考:MySQL幻读详解及解决方法_学而不思则忘的博客-CSDN博客_mysql 幻读】
select ...for update引发的死锁问题
插入意向锁与间隙锁是冲突的,所以当其它事务持有该间隙的间隙锁时,需要等待其它事务释放间隙锁之后,才能获取到插入意向锁。而间隙锁与间隙锁之间是兼容的,所以所以两个事务中 select ... for update 语句并不会相互影响。
间隙锁在本质上是不区分共享间隙锁或互斥间隙锁的,而且间隙锁是不互斥的,即两个事务可以同时持有包含共同间隙的间隙锁。
插入意向锁是一种特殊的间隙锁,但不同于间隙锁的是,该锁只用于并发插入操作。
关键问题是两个事务都可以获取间隙锁,并都在等待对方的事务释放间隙锁,导致死锁。
如果update后的where为非索引,那么会锁住整张表。
每插入一条新记录,都需要看一下待插入记录的下一条记录上是否已经被加了间隙锁,如果已加间隙锁,那 Insert 语句应该被阻塞,并生成一个插入意向锁 。
参考:面试官:解释下什么是死锁?为什么会发生死锁?怎么避免死锁? - 知乎
MySQL for update 死锁案例 - 墨天轮