mysql 行锁的类型
发布网友
发布时间:2024-08-19 23:26
我来回答
共1个回答
热心网友
时间:2024-08-25 07:30
在MySQL 8.0.29版本的REPEATABLE-READ隔离级别下,行锁的类型有共享锁(S,REC_NOT_GAP和S,GAP)和独占锁(X,REC_NOT_GAP和X,GAP)。独占锁包括插入意向锁(X,INSERT_INTENTION)和X,GAP,INSERT_INTENTION,后者允许与其他插入锁兼容。当在没有索引的列上执行读或更新时,由于全表扫描,会加锁整个表,最终锁定在主键索引上,限制了对已有记录的修改和插入(因为所有主键间隙都被锁定)。
对于没有索引的id列,执行`for update`操作会锁住所有id小于6的记录,形成(-oo,3]和(3,6)的区间。如果试图在这些区间之外的id=6进行更新,会遇到阻塞。同时,由于间隙锁不会相互阻塞,id=2的查询可以执行,而id=5的插入则会因为防止幻读而被阻塞。
在`id=6`的情况下,`for update`操作会锁定(6,9]和(9,+oo)的区间,使得id>6的更新被阻塞。如果查询id=4或id=5,由于这些记录不存在,不会影响锁定范围。
对于name列的查询,如果name='n6',可以执行,因为间隙锁兼容。然而,当查询name='n3'时,由于name索引的临建锁冲突,操作无法执行。
在二级索引(非唯一索引)上,锁定行为更为复杂。比如,对于name='n6',即使索引范围包含n6,只会加临建锁;而对于name='n3',由于索引记录不存在,会在对应区间加间隙锁,但不会锁定主键。
总结来说,MySQL在可重复读模式下,行锁的使用取决于隔离级别、索引的存在以及查询条件,通常以临键锁或间隙锁的形式存在,不会加行锁到不存在的记录。理解这些锁的类型和行为对于优化查询性能和避免并发问题至关重要。