程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQLInnoDB鎖機制(一)

MySQLInnoDB鎖機制(一)

編輯:MySQL綜合教程

MySQLInnoDB鎖機制(一)


MySQL InnoDB一共有四種鎖:共享鎖(讀鎖,S鎖)、排他鎖(寫鎖,X鎖)、意向共享鎖(IS鎖)和意向排他鎖(IX鎖)。其中共享鎖與排他鎖屬於行級鎖,另外兩個意向鎖屬於表級鎖。

共享鎖(讀鎖,S鎖):若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放S鎖。排他鎖(寫鎖,X鎖):若事務T對數據對象A加上X鎖,則只允許T讀取和修改A,其他事務不能再對A加作何類型的鎖,直到T釋放A上的X鎖。意向共享鎖(IS鎖):事務T在對表中數據對象加S鎖前,首先需要對該表加IS(或更強的IX)鎖。意向排他鎖(IX鎖):事務T在對表中的數據對象加X鎖前,首先需要對該表加IX鎖。

比如SELECT ... FROM T1 LOCK IN SHARE MODE語句,首先會對表T1加IS鎖,成功加上IS鎖後才會對數據加S鎖。

同樣,SELECT ... FROM T1 FOR UPDATE語句,首先會對表T1加IX鎖,成功加上IX鎖後才會對數據加X鎖。

MySQL InnoDB 鎖兼容陣列 X IX S IS X ? ? ? ? IX ? ? ? ? S ? ? ? ? IS ? ? ? ?

MySQL官網上有個死鎖的例子,但分析得過於概括,這裡我們詳細分析一下。

首先,會話S1以SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE查詢,該語句首先會對t表加IS鎖,接著會對數據(i = 1)加S鎖。

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
Query OK, 0 rows affected (1.07 sec)

mysql> INSERT INTO t (i) VALUES(1);
Query OK, 1 row affected (0.09 sec)

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.10 sec)
接著,會話S2執行DELETE FROM t WHERE i = 1,該語句嘗試對t表加IX鎖,由於IX鎖與IS鎖是兼容的,所以成功對t表加IX鎖。接著繼續對數據(i = 1)加X鎖,但數據已經被會話S1事務加了S鎖了,所以會話S2等待。

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM t WHERE i = 1;
接著,會話S1也執行DELETE FROM t WHERE i = 1,該語句首先對t表加IX鎖,雖然會話S2已經對t表加了IX鎖,但IX鎖與IX鎖之間是兼容的,所以成功對t表加上IX鎖。接著會話S1會對數據(i = 1)加X鎖,此時發現會話S2占有的IX鎖與X鎖不兼容,所以會話S1也等待。就這樣,會話S1等S2釋放IX鎖,而會話S2等S1釋放S鎖,從而死鎖發生。
mysql> DELETE FROM t WHERE i = 1;
Query OK, 1 row affected (0.00 sec)

mysql>
會話S2發生死鎖。
mysql> DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
mysql>

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved