昨天读到了一篇文章[1],里面讲,面试官说mysql的可重复读级别下有解决幻读的方式,最后公布了答案,是在sql后面加for update。这么说倒是没错,但是这种问法给我一种奇怪的感觉,因为for update无论在哪个隔离级别下,都能提供x锁进行锁定防止幻读,而next key lock,是x锁的三种实现算法之一,next key lock,也不应该翻译为间隙锁。下面我们一一讲来。
一,mysql的锁
mysql的锁,
按照读或写,分成s锁和x锁
按照锁的范围,分成表锁和行锁
按照意向锁的读或写,分成is锁和ix锁。其中is锁和ix锁是表锁,但不是真的用排他锁锁表,而是一种共享锁,旨在告诉其他线程表中有s锁或者x锁;而s锁和x锁是真的加了排他锁,s锁是对读共享对写排他,x锁是对其他线程的任何操作都排他,且s锁和x锁都是行锁。
而最后一个,mysql行锁的三种算法。
行锁(Record Lock)
,只锁单行
记录本身。
间隙锁(Gap Lock)
,锁住记录两边的记录,但是对记录本身,不加锁。
临键锁(Next Key Lock)
,即锁住记录本身,也锁住记录两边,这种锁的范围是左闭右开。还有一种锁,叫做Previous Key Lock
,和Next Key Lock类似,区别只是锁的范围左开右闭。它们都来自于谓词锁
,即锁住满足某一查询条件的所有数据项,它不仅包括当前在数据库中满足条件的记录,也包括即将要插入,更新或删除到数据库并满足查询条件的数据项。
下图来自《MySQL技术内幕 InnoDB存储引擎》一书。