Innodb中常見SQL語句設定的鎖型別

2021-09-19 17:50:30 字數 2637 閱讀 1107

除了serializable隔離級別,這種sql都是一致性非鎖定讀,不加鎖;在serializable級別,這種sql加next-key鎖。

這種sql加s型別的next-key鎖。例如,在會話1上開啟事務1,執行如下操作(num列上建有普通二級索引):

mysql> start transaction;

query ok, 0 rows affected (0.01 sec)

mysql> select * from lock_test;

+----+-----+------+

| id | num | name |

+----+-----+------+

| 1 | 1 | jdd |

| 2 | 43 | hjh |

| 3 | 6 | ew |

| 4 | 4 | dd |

| 5 | 12 | t |

| 6 | 32 | hu |

| 32 | 45 | gj |

+----+-----+------+

mysql> select * from lock_test where num=12 lock in share mode;

+----+-----+------+

| id | num | name |

+----+-----+------+

| 5 | 12 | t |

+----+-----+------+

會話2上開啟事務2,執行如下操作:

mysql> start transaction;

query ok, 0 rows affected (0.00 sec)

mysql> insert into lock_test values(null,8,'hgj');

^c^c -- query aborted

error 1317 (70100): query execution was interrupted

mysql> insert into lock_test values(null,31,'hgj');

^c^c -- query aborted

error 1317 (70100): query execution was interrupted

插入num=8和31,都發生阻塞,說明事務1執行的語句產生了間隙鎖。若再在事務2中執行語句「select * from lock_test where num=12 lock in share mode;」,不會發生阻塞,說明num=12上加的是s鎖,所以鎖相容。

這種sql加x型別的next-key鎖。

rr及其以上隔離級別下,該語句會加next-key鎖;在rc級別,只加record鎖。

rr及其以上隔離級別下,該語句會加next-key鎖;在rc級別,只加record鎖。

這裡指簡單的insert(****** insert),即不加on duplicate key update和select子句的insert語句。這種sql語句只會在它插入的行上加x鎖,而不會加next-key鎖。

但是對於唯一列(unique列和主鍵列),如果多個事務向同一行插入資料,那麼第乙個事務持有該行的x鎖,之後的事務將向這個重複的索引記錄行上請求加s鎖,並且此時發生鎖等待現象。這個時候,還有可能會有死鎖發生:

例如假設有個如下結構的innodb表:

create table t1 (i int, primary key (i)) engine = innodb;
假設有三個會話依次執行如下操作:

session 1:

start transaction;

insert into t1 values(1);

session 2:

start transaction;

insert into t1 values(1);

session 3:

start transaction;

insert into t1 values(1);

session 1:

rollback;

會話1獲得i=1資料行上的x鎖,之後會話2和會話3的操作因為可能會導致重複鍵錯誤,所以它們均請求i=1上的s鎖而發生鎖等待;當會話1回滾後,i=1資料行上的x鎖被釋放(或者說沒有了i=1的行),此時鎖請求佇列裡的會話2和會話3都可以獲得s鎖,但此時將產生死鎖:由於它們都持有該資料行上的s鎖,因此兩個會話都獲取不到資料行上的x鎖。

上面的例子,如果i是unique key,情況也同樣適用。

該sql與****** insert的不同之處在於,當發生重複鍵錯誤時,在要更新的行上設定x型別的next-key鎖

這種sql在t表被插入的行上加x record lock;在s表上,若事務隔離級別不是serializable,innodb在s表上是一致性非鎖定讀方式(即不加鎖)。如果是在serializable級別,innodb將在s表上加s型別的next-key鎖。

加鎖方式和insert … select方式相同。

包括lock tables tb_name read/write語句,這種語句加的是表鎖(table locks),設定表鎖的是innodb層之上的mysql server層

sql 中常見的控制流語句

控制流語句 1 begin end 2 if else 例如 if exists select from 表名稱 begin selct from 表名稱 end 3 while break countinue while語句用於設定重複執行的sql語句或者語句塊 continue語句可以讓語句跳過...

oracle 中常見日期查詢語句

1.查詢上月末的日期 select last day add months sysdate,1 from dual 2.查詢本週星期一的日期 select trunc sysdate,day 1 from dual 3.計算年初至今的天數 select ceil sysdate trunc sysd...

常見sql語句操作

1 基本語法 create table testfmj id int identity 1,1 identity表示自增列的意思,而int identity 1,1 表示從1開始遞增,每次自增1。name varchar 30 default abc varchar 30 age int defau...