SELECT ... FROM 是一致性读,一般情况下只读取数据库快照,不会加锁。在事务隔离级别为 SERIALIZABLE 时会被转换成 LOCK IN SHARE MODE,查询将会在其找到的记录前加上 next-key lock 。如果使用唯一索引查询单条记录,就只需要一个 index-record lock。
SELECT ... FOR UPDATE/SELECT ... LOCK IN SHARE MODE 被扫描的索引记录都将加锁,并期望尽快地释放不匹配 WHERE 条件的行的锁。在某些场景,结果集与源数据之间的关系在查询中丢失,将导致这些行的锁不能立即释放。如:在 UNION 被扫描到的行在被计算出是否匹配结果集前可能会被插入到一张临时表中。这种情况下,临时表的行与源数据行的关系会丢失,并且源数据行在查询执行结束前不会解锁。
-- A similar situation occurs if the table already contains a row with key value 1 and three sessions perform the following operations in order: -- session1 START TRANSACTION; DELETEFROM t1 WHERE i =1; -- session2 START TRANSACTION; INSERTINTO t1 VALUES(1); -- session3 START TRANSACTION; INSERTINTO t1 VALUES(1); -- session1 COMMIT;