1. 程式人生 > 資料庫 >MySQL中的行級鎖定示例詳解

MySQL中的行級鎖定示例詳解

前言

鎖是在執行多執行緒時用於強行限定資源訪問的同步機制,資料庫鎖根據鎖的粒度可分為行級鎖,表級鎖和頁級鎖

行級鎖

行級鎖是mysql中粒度最細的一種鎖機制,表示只對當前所操作的行進行加鎖,行級鎖發生衝突的概率很低,其粒度最小,但是加鎖的代價最大。行級鎖分為共享鎖和排他鎖。

特點:

開銷大,加鎖慢,會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最大,併發性也高;

實現原理:

InnoDB行鎖是通過給索引項加鎖來實現的,這一點mysql和oracle不同,後者是通過在資料庫中對相應的資料行加鎖來實現的,InnoDB這種行級鎖決定,只有通過索引條件來檢索資料,才能使用行級鎖,否則,直接使用表級鎖。特別注意:使用行級鎖一定要使用索引

舉個栗子:

建立表結構

CREATE TABLE `developerinfo` (
 `userID` bigint(20) NOT NULL,`name` varchar(255) DEFAULT NULL,`passWord` varchar(255) DEFAULT NULL,PRIMARY KEY (`userID`),KEY `PASSWORD_INDEX` (`passWord`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入資料

INSERT INTO `developerinfo` VALUES ('1','liujie','123456');
INSERT INTO `developerinfo` VALUES ('2','yitong','123');
INSERT INTO `developerinfo` VALUES ('3','tong','123456');

(1)通過主鍵索引來查詢資料庫使用行鎖

開啟三個命令列視窗進行測試

命令列視窗1 命令列視窗2 命令列視窗3

mysql> set autocommit = 0;
Query OK,0 rows affected
mysql> select * from developerinfo where userid = '1' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 1 | liujie | 123456 |
+--------+--------+----------+
1 row in set 
|mysql> set autocommit = 0;
Query OK,0 rows affected
mysql> select * from developerinfo where userid = '1' for update;
等待
|mysql> set autocommit = 0;
Query OK,0 rows affected
mysql> select * from developerinfo where userid = '3' for update;
+--------+------+----------+
| userID | name | passWord |
+--------+------+----------+
| 3 | tong | 123456 |
+--------+------+----------+
1 row in set
|mysql> commit;
Query OK,0 rows affected mysql> select * from developerinfo where userid = '1' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 1 | liujie | 123456 |
+--------+--------+----------+
1 row in set

(2)查詢非索引的欄位來查詢資料庫使用行鎖

開啟兩個命令列視窗進行測試

命令列視窗1 命令列視窗2

|mysql> set autocommit=0;
Query OK,0 rows affected
mysql> select * from developerinfo where name = 'liujie' for update;
+--------+--------+----------+
userID name passWord
+--------+--------+----------+
1 liujie 123456
+--------+--------+----------+
1 row in set |mysql> set autocommit=0;
Query OK,0 rows affected
mysql> select * from developerinfo where name = 'tong' for update;
等待|
mysql> commit;
Query OK,0 rows affected mysql> select * from developerinfo where name = 'liujie' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 1 | liujie | 123456 |
+--------+--------+----------+
1 row in set

##### (3)查詢非唯一索引欄位來查詢資料庫使用行鎖鎖住多行

mysql的行鎖是針對索引假的鎖,不是針對記錄,所以可能會出現鎖住不同記錄的場景

開啟三個命令列視窗進行測試

命令列視窗1命令列視窗2命令列視窗3

mysql> set autocommit=0;
Query OK,0 rows affected
mysql> select * from developerinfo where password = '123456
' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 1 | liujie | 123456 |
| 3 | tong | 123456 |
+--------+--------+----------+
2 rows in set mysql> set autocommit =0 ;
Query OK,0 rows affected
mysql> select * from developerinfo where userid = '1' for update;

等待

mysql> set autocommit = 0;
Query OK,0 rows affected
mysql> select * from developerinfo where userid = '2
' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 2 | yitong | 123 |
+--------+--------+----------+
1 row in set
commit; mysql> select * from developerinfo where userid = '1' for update;
+--------+--------+----------+
| userID | name | passWord |
+--------+--------+----------+
| 1 | liujie | 123456 |
+--------+--------+----------+
1 row in set

##### (4)條件中使用索引來操作檢索資料庫時,是否使用索引還需有mysql通過判斷不同執行計劃來決定,是否使用該索引,如需判定如何使用explain來判斷索引,請聽下回分解

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。