除了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...