mysql鎖之三種行級(jí)鎖介紹

本文主要介紹
1.MySQL三種行鎖介紹
2.RR模式下,next-key lock為什么可以解決幻讀問(wèn)題

首先,創(chuàng)建一張表:
mysql> show create table test01\G
*************************** 1. row ***************************
       Table: test01
Create Table: CREATE TABLE `test01` (
  `c1` bigint(20) NOT NULL AUTO_INCREMENT,
  `c2` int(11) DEFAULT NULL,
  `c3` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
初始化數(shù)據(jù):
mysql> select * from test01;
+----+------+------+
| c1 | c2   | c3   |
+----+------+------+
|  1 |    1 | a    |
|  2 |    2 | b    |
|  3 |    3 | c    |
|  4 |    4 | d    |
|  5 |    5 | e    |
+----+------+------+
5 rows in set (0.00 sec)

record lock:
在數(shù)據(jù)行本身加的鎖。

會(huì)話(huà)A
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)

mysql> select c1 from test01 where c1=1 for update;
+----+
| c1 |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

會(huì)話(huà)B
mysql> update test01 set c1=6 where c1=1;   --hang

c1=1上有record lock,所以會(huì)話(huà)B無(wú)法修改。
mysql> SHOW ENGINE INNODB STATUS\G
------- TRX HAS BEEN WAITING 4 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 3 n bits 72 index PRIMARY of table `ming`.`test01` trx id 1807 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 8; hex 8000000000000001; asc         ;;
 1: len 6; hex 000000000708; asc       ;;
 2: len 7; hex a80000011c0110; asc        ;;
 3: len 4; hex 80000001; asc     ;;
 4: len 1; hex 61; asc a;;

gap lock:
在gap上加的鎖,不包括記錄本身。
需要建立一個(gè)非唯一性的索引,不能是主鍵或者唯一性索引,否則只有record lock。
mysql> create index idx_test01_c2 on test01(c2);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
初始化數(shù)據(jù):
mysql> select * from test01;
+----+------+------+
| c1 | c2   | c3   |
+----+------+------+
|  1 |    1 | a    |
|  3 |    3 | c    |
|  5 |    5 | e    |
|  7 |    7 | e    |
+----+------+------+
4 rows in set (0.00 sec)

會(huì)話(huà)A:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select c2 from test01 where c2>3 and c2<5 for update;
Empty set (0.00 sec)

會(huì)話(huà)B
mysql> insert into test01 select 4,4,'e';  --hang
(3,3)與(5,5)之間的gap被鎖住了,所以無(wú)法插入(4,4)。
------- TRX HAS BEEN WAITING 32 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 4 n bits 72 index idx_test01_c2 of table `ming`.`test01` trx id 1925 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 8; hex 8000000000000005; asc         ;;

此時(shí)c2=3和c2=5兩行數(shù)據(jù)是可以更改的,但是改變后的值不能在現(xiàn)在的gap中。關(guān)于數(shù)據(jù)行的gap具體的可以參考下面的例子:、 next-key lock
對(duì)數(shù)據(jù)記錄本身和gap都加鎖,相當(dāng)于record lock + gap lock。

c3列無(wú)用,刪除
mysql> alter table test01 drop column c3;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

初始化數(shù)據(jù):
mysql> select * from test01;
+----+------+
| c1 | c2   |
+----+------+
|  2 |    2 |
|  5 |    5 |
|  7 |    7 |
+----+------+
3 rows in set (0.00 sec)

會(huì)話(huà)A:
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test01 where c2=5 for update;
+----+------+
| c1 | c2   |
+----+------+
|  5 |    5 |
+----+------+
1 row in set (0.00 sec)

會(huì)話(huà)B:
insert into test01 select 1,2;      --ok
insert into test01 select 3,2;      --hang
insert into test01 select 4,5;      --hang
insert into test01 select 6,5;      --hang
insert into test01 select 8,7;      --ok
update test01 set c2=3 where c2=2;  --hang
update test01 set c2=1 where c2=2;  --ok
update test01 set c2=6 where c2=7;  --hang
update test01 set c2=8 where c2=7;  --ok
會(huì)話(huà)A在c2=5及gap上加了next-key lock,在數(shù)據(jù)行本身加了record lock,在c2=5數(shù)據(jù)行與其相鄰的上下兩行數(shù)據(jù)(c2=2,c2=7)之間的gap加了gap lock。
注意到(1,2)可以插入,但是(3,2)卻無(wú)法插入,有人或許會(huì)有疑問(wèn),c2都是2,為什么一個(gè)可以插入一個(gè)不能插入?注意,next-key lock是在索引上加鎖,索引是有順序的,如下:
(1,2)--> (2,2) -->  (5,5)
                |-gap-|  
注意到(1,2)在gap之外,所以是可以插入的。假設(shè)(3,2)可以插入,那么它們?cè)谒饕械捻樞驅(qū)⑹?br/>(2,2) --> (3,2) --> (5,5)
      |----gap----|
(3,2)將會(huì)插入到gap中,所以(3,2)是無(wú)法插入的。
會(huì)話(huà)B其它的sql也是這個(gè)道理。

經(jīng)常看到一個(gè)說(shuō)法是,next-key lock解決了RR隔離級(jí)別下的幻讀問(wèn)題,那么是如何做到的呢?
什么叫幻讀?
一個(gè)事務(wù)里面,多次查詢(xún)出的結(jié)果集不一致,這種情況就叫做幻讀。
下面是幻讀現(xiàn)象的一個(gè)例子:
會(huì)話(huà)A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test01;
+----+------+
| c1 | c2   |
+----+------+
|  1 |    1 |
|  5 |    5 |
|  7 |    7 |
+----+------+
3 rows in set (0.00 sec)

會(huì)話(huà)B
mysql> insert into test01 select 8,8 ;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

會(huì)話(huà)A
mysql> select * from test01;
+----+------+
| c1 | c2   |
+----+------+
|  1 |    1 |
|  5 |    5 |
|  7 |    7 |
+----+------+
3 rows in set (0.00 sec)
mysql> insert  into test01 select 8,8 ;
ERROR 1062 (23000): Duplicate entry '8' for key 'PRIMARY'
會(huì)話(huà)A明明沒(méi)有讀到c1=8的記錄,但就是無(wú)法插入,這就出現(xiàn)了幻讀現(xiàn)象。

如果會(huì)話(huà)A在開(kāi)始事務(wù)后,
select * from test01 for update;
或者
select * from test01 lock in share mode;
那么會(huì)話(huà)B根本無(wú)法對(duì)數(shù)據(jù)做任何修改,那么這也就解決了幻讀問(wèn)題。

成都創(chuàng)新互聯(lián)公司擁有10多年成都網(wǎng)站建設(shè)工作經(jīng)驗(yàn),為各大企業(yè)提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)服務(wù),對(duì)于網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、APP應(yīng)用開(kāi)發(fā)、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、程序開(kāi)發(fā)、網(wǎng)站優(yōu)化(SEO優(yōu)化)、微網(wǎng)站、空間域名等,憑借多年來(lái)在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了很多網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷(xiāo)經(jīng)驗(yàn),集策劃、開(kāi)發(fā)、設(shè)計(jì)、營(yíng)銷(xiāo)、管理等網(wǎng)站化運(yùn)作于一體,具備承接各種規(guī)模類(lèi)型的網(wǎng)站建設(shè)項(xiàng)目的能力。

文章標(biāo)題:mysql鎖之三種行級(jí)鎖介紹
網(wǎng)站鏈接:http://bm7419.com/article10/ipdsgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、小程序開(kāi)發(fā)、網(wǎng)站內(nèi)鏈Google、做網(wǎng)站品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)