据我所知缺口锁是用来防止幻读的,我通过谷歌搜索发现大部分文章中缺口锁都是通过锁定读来设置的。
差距锁就是对索引记录之间的间隙进行锁定,或者说对第一条索引记录之前或最后一条索引记录之后的间隙进行锁定。比如说 SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 防止其他事务在t.c1列中插入一个15的值,不管该列中是否已经有任何这样的值,因为范围内所有现有值之间的空隙都被锁定。
https:/dev.mysql.comdocrefman8.0eninnodb-locking.html#innodb-gap-lock。
我想这样(在锁定读取时设置间隙锁定)就可以了。为什么要这样做呢?更新, 删去 同时设置间隙锁定。
更新... WHERE ... 设置 一键锁 在搜索遇到的每一条记录上。但是,对于使用唯一索引锁定行的语句,只需要一个索引记录锁来搜索唯一的行。
https:/dev.mysql.comdocrefman8.0eninnodb-lock-set.html。
而另一个问题是,如果没有合适的索引可以附加间隙锁,会怎么样?是否会回落到对整个表的锁定?
这里我们假设使用默认的事务隔离级别Repeatable Read。
这取决于你的SELECT、UPDATE或DELETE中的条件。它们设置间隙锁是为了防止其他并发会话向集合中添加会被条件匹配的行。
在InnoDB中,锁定语句总是锁定最近提交的行版本。所以它们并不真正服从REPEATABLE READ快照。它们的行为更像READ-COMMITTED。
因此,如果你做一个这样的语句。
UPDATE FROM MyTable SET ... WHERE created_at > '2020-03-22';
它必须锁定create_at的最高值之后的空白, 这将阻止其他会话添加新的记录。
这是要 模拟 REPEATABLE READ,以确保如果你再次运行相同的UPDATE,会影响相同的行,不会意外影响新的行。