InnoDB有三種行鎖的算法:html
1,Record Lock:單個行記錄上的鎖mysql
2,Gap Lock:間隙鎖,鎖定一個範圍,但不包括記錄自己算法
3,Next-Key Lock:Record Lock + Gap Lock,鎖定一個範圍,而且鎖定記錄自己sql
SELECT @@global.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)測試
create table t(a int,key idx_a(a))engine =innodb; insert into t values(1),(3),(5),(8),(11);
上面索引值有1,3,5,8,11,其記錄的GAP的區間以下:(-∞,1],(1,3],(3,5],(5,8],(8,11],(11,+∞)優化
--鎖定存在的值 select * from t where a = 8 for update; --鎖定不存在的值 select * from t where a = 9 for update;
插入5,6,7,8,9,10 會被鎖住, 其餘正常。spa
mysql> set global transaction isolation level read committed;
SHOW VARIABLES LIKE '%innodb_locks_unsafe_for_binlog%';
InnoDB對於行的查詢都是採用了Next-Key Lock的算法,鎖定的不是單個值,而是一個範圍。code
當查詢的條件含有惟一索引時,Next-Key Lock 會進行優化,將其降級爲Record Lock。htm
啓用innodb_locks_unsafe_for_binlog或read-committed後,能夠使得
blogInnoDB
gap鎖最小化,可是在兩種場景(外鍵約束和惟一索引)中,仍然不可避免的存在gap鎖。
出處:
參考: