mysql鎖 實戰測試程式碼

神馬和浮雲發表於2014-12-18
儲存引擎 支援的鎖定
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執行成功。

測試結果:

寫鎖後,執行寫鎖的執行緒可進行讀和寫,其他執行緒不可進行讀和寫

 

相關文章