行鎖的三種演算法

2022-03-28 09:59:44 字數 1835 閱讀 2846

record lock總是會鎖住索引記錄,如果innodb儲存引擎表在建立的時候沒有設定任何乙個索引,那麼這時innodb儲存引擎會使用隱式的主鍵來進行鎖定。

設計目的:是為了解決phantom problem(幻象/幻讀),利用這種鎖技術,鎖定的不是單個值,而是乙個範圍。

next-key lock是結合了gap lock和record lock的一種鎖定演算法,在此種演算法下,innodb對於行的查詢都是採用這種鎖定演算法。

例如:有10、11、13、20這四個值,那麼索引可能被next-key locking的區間為:

1、(-∞,10]

2、(10,11]

3、(11,13]

4、(13,20]

5、(20,+∞)

除了next-key locking,還有previous-key locking,如上面的例子,可鎖定的區間為:

1、(-∞,10)

2、  [10,11)

3、  [11,13)

4、  [13,20)

5、  [20,+∞)

然而,當查詢的索引含有唯一屬性時,innodb儲存引擎對next-key lock進行優化,將其降級為record lock,即僅鎖住索引本身,而不是範圍。如表中有1,2,5的id資料:

會話a首先對a=5進行x鎖。而由於a是主鍵且唯一,因此鎖定的僅是5這個值,而不是(2,5)的範圍,這樣在b中插入值4不會阻塞,可以立即插入並返回。即鎖定由next-key lock演算法降級為record lock,從而提高了併發性。

next-key lock降級為record lock僅在查詢的列是唯一索引的情況下。

若是輔助索引,則情況會完全不同如:

create table z(a int,b int,primary key(a),key(b))

insert into z select 1,1;

insert into z select 3,1;

insert into z select 5,3;

insert into z select 7,6;

insert into z select 10,8;

表z的b列是輔助索引,若在會話a中執行下面的sql:

select * from z where b=3 for update;

這是sql語句通過索引列b進行查詢,因此其使用傳統的next-key locking加鎖,並且由於兩個索引,其需要分別進行鎖定。對於聚集索引,其僅對a等於5的索引加上record lock。對於輔助索引,其加上的是next-key lock,鎖定的範圍是(1,3),需要注意的是,innodb儲存引擎還會對輔助索引下乙個鍵值加上gap lock,即還有乙個輔助索引的範圍為(1,6)的鎖,因此,在b會話中執行下面的sql語句,都會被阻塞:

select * form z where a=5 lock in share mode;

insert into z select 4,2;

insert into z select 6,5;

而執行下面的語句,不會阻塞:

insert into z select 8,6;

insert into z select 2,0;

insert into z select 6,7;

在預設的事務隔離級別下,即repeatable read下,innodb儲存引擎採用next-key locking機制來避免phantom problem(幻象問題)

MySQL InnoDB行鎖演算法 三種詳解

字面意思,給一行資料加鎖。innodb 行鎖是通過給索引上的索引項加鎖來實現的,如果沒有索引,innodb 將通過隱藏的聚簇索引來對記錄加鎖。注意 行鎖必須有索引才能實現,否則會自動鎖全表,那麼就不是行鎖了。兩個事務不能鎖同乙個索引。1 record lock 記錄鎖,單個行記錄上的鎖 鎖住具體的索...

三種列表以及行級塊三種元素的轉變

在講列表之前先說乙個剛學的選擇器 萬用字元選擇器 萬用字元選擇器有好處也有壞處,好處就是能一次選中所有的標籤,省事 短處就是把不必要的標籤也會選中,增加瀏覽器的負荷。最好的解決辦法就是按需求選擇。無序列表ul 內部必須有子標籤 ul天生自帶內外邊邊距,還帶乙個p標籤 有序列表ol 內部必須有子標籤 ...

行轉列的三種實現方式

public class test delete 把非表頭的每個格仔的下標弄出來 this find td each function set.push row testdiv after 一行二列 set 0 1 testdiv after 二行五列 set 1 4 var seted 確定新陣列...