儲存引擎 | 支援的鎖定 |
MyISAM | 表級鎖 |
MEMORY | 表級鎖 |
InnoDB | 行級鎖 |
BDB | 頁面鎖 |
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。
鎖定方式 | 執行鎖定的執行緒 讀 | 其他執行緒 讀 | 執行鎖定的執行緒 寫 | 其他執行緒 寫 |
讀鎖 | 可讀 | 可讀 | 不可寫 | 不可寫 |
寫鎖 | 可讀 | 不可讀 | 可寫 | 不可寫 |
涉及工具:Navicat和SQLyog(不能使用phpMyAdmin)
測試程式碼
測試一:讀鎖。說明:自己與其他執行緒只能讀取該表
在Navicat中執行以下程式碼
mysql> lock table `cat` READ; Query OK, 0 rows affected mysql> SELECT * FROM `cat` WHERE 1; +----+--------+ | id | remark | +----+--------+ | 1 | ceshi | | 2 | 22222 | | 3 | 33333 | +----+--------+ 3 rows in set mysql> UPDATE `cat` SET remark= 'Navicat' WHERE id=1; 1099 - Table 'cat' was locked with a READ lock and can't be updated
在SQLyog中執行
mysql> SELECT * FROM `cat` WHERE 1;
+----+--------+
| id | remark |
+----+--------+
| 1 | ceshi |
| 2 | 22222 |
| 3 | 33333 |
+----+--------+
3 rows in set mysql> UPDATE `cat` SET remark= 'SQLyog' WHERE id=1
SQLyog執行UPDATE時,一直都是執行中。當解鎖時,執行成功。
在Navicat中執行解鎖操作
mysql> unlock tables;
執行後,SQLyog的UPDATE執行成功。
測試結果:
當進行讀鎖時,鎖定執行緒可進行查詢操作,不可進行寫入操作。其他執行緒可進行查詢操作,不可進行寫入操作。
測試一:寫鎖。說明:只有當前執行緒能夠對錶進行寫入操作(其他執行緒也無法讀這部分資料)
在Navicat中執行以下程式碼
mysql> LOCK TABLE cat WRITE; Query OK, 0 rows affected mysql> select * from `cat` where 1; +----+--------+ | id | remark | +----+--------+ | 1 | SQLyog | | 2 | 22222 | | 3 | 33333 | +----+--------+ 3 rows in set mysql> update `cat` set remark= 'Navicat' where id=1; Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0
然後在SQLyog中執行
mysql> select * from `cat` where 1;
和
mysql> update `cat` set remark= 'Navicat' where id=1;
可見都是一直是執行狀態。只有解鎖後,SQLyog才能執行成功
在Navicat中執行解鎖操作
mysql> unlock tables;
SQLyog執行成功。
測試結果:
寫鎖後,執行寫鎖的執行緒可進行讀和寫,其他執行緒不可進行讀和寫