RR级别-多线程环境下-for update+插入操作包含的间隙锁+插入意向锁引发的死锁问题

 

记录select for update mysql 死锁问题_执行select ... where ... for update是否会造成死锁(deadlock)-CSDN博客

 

两段锁协议和一次封锁法

MySQL 中的锁机制 - 真正的飞鱼 - 博客园 (cnblogs.com)

 

MYSQL锁机制

Mysql「Select For Update」锁机制分析 - 掘金 (juejin.cn)

 

在MySQL中,当两个事务(事务A和事务B)尝试使用FOR UPDATE锁定不同的行,但是存在行的交集时,理论上是不会出现一个事务锁定了某些行,而另一个事务锁定了剩余行的情况。这是因为FOR UPDATE锁定操作是原子性的,并且数据库会保证事务的隔离性。
 
在你的例子中,如果事务A和事务B几乎同时执行,它们的行为可能是这样的:
 
事务A 开始执行,尝试锁定id为a、b、c的行。
事务B 开始执行,尝试锁定id为c、b、a的行(注意:顺序不影响锁定结果)。
可能出现的情况有:
 
情况1:事务A先锁定 - 如果事务A先于事务B执行并且成功锁定了id为a、b、c的行,那么当事务B尝试锁定这些行时,它会被阻塞,直到事务A释放了它的锁(通过提交或回滚)。
 
情况2:事务B先锁定 - 如果事务B先于事务A执行并且成功锁定了id为c、b的行,那么当事务A尝试锁定这些行时,它同样会被阻塞。
 
情况3:同时锁定 - 如果两个事务尝试同时锁定相同的行,那么谁会首先成功锁定取决于许多因素,如数据库的锁定机制、查询的执行计划、数据的物理存储等。但是,一旦一个事务成功锁定了某些行,其他事务在尝试锁定这些行时会被阻塞。
 
在标准的隔离级别(如Repeatable Read)下,事务会看到一致的视图,并且锁定操作会保持原子性。这意味着在任何给定时间点,要么事务A持有所有必要的锁,要么事务B持有,但不可能出现一个事务锁定一部分行,而另一个事务锁定剩余行的情况。
 
此外,如果确实发生了死锁,MySQL的死锁检测机制会识别这种情况,并选择牺牲一个事务来解决死锁,通常是回滚持有最少行级排他锁的事务。
 
因此,根据标准的事务隔离和锁定规则,不会出现事务A锁定了a,事务B锁定了c,而两者都在等待剩余锁的情况。事务会等待直到它可以获得所有需要的锁,否则不会继续执行。
posted @ 2024-05-09 11:22  忙碌了一整天的L师傅  阅读(6)  评论(0编辑  收藏  举报