日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql数据库的行级锁有几种_mysql锁之三种行级锁介绍

發(fā)布時間:2024/9/15 数据库 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql数据库的行级锁有几种_mysql锁之三种行级锁介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文主要介紹

1.mysql三種行鎖介紹

2.RR模式下,next-key lock為什么可以解決幻讀問題

首先,創(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ù)行本身加的鎖。

會話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)

會話B

mysql> update test01 set c1=6 where c1=1;?? --hang

c1=1上有record lock,所以會話B無法修改。

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上加的鎖,不包括記錄本身。

需要建立一個非唯一性的索引,不能是主鍵或者唯一性索引,否則只有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)

會話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)

會話B

mysql> insert into test01 select 4,4,'e';? --hang

(3,3)與(5,5)之間的gap被鎖住了,所以無法插入(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???????? ;;

此時c2=3和c2=5兩行數(shù)據(jù)是可以更改的,但是改變后的值不能在現(xiàn)在的gap中。關(guān)于數(shù)據(jù)行的gap具體的可以參考下面的例子:、

next-key lock

對數(shù)據(jù)記錄本身和gap都加鎖,相當(dāng)于record lock + gap lock。

c3列無用,刪除

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)

會話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)

會話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

會話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)卻無法插入,有人或許會有疑問,c2都是2,為什么一個可以插入一個不能插入?注意,next-key lock是在索引上加鎖,索引是有順序的,如下:

(1,2)--> (2,2) -->? (5,5)

|-gap-|

注意到(1,2)在gap之外,所以是可以插入的。假設(shè)(3,2)可以插入,那么它們在索引中的順序?qū)⑹?/p>

(2,2) --> (3,2) --> (5,5)

|----gap----|

(3,2)將會插入到gap中,所以(3,2)是無法插入的。

會話B其它的sql也是這個道理。

經(jīng)常看到一個說法是,next-key lock解決了RR隔離級別下的幻讀問題,那么是如何做到的呢?

什么叫幻讀?

一個事務(wù)里面,多次查詢出的結(jié)果集不一致,這種情況就叫做幻讀。

下面是幻讀現(xiàn)象的一個例子:

會話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)

會話B

mysql> insert into test01 select 8,8 ;

Query OK, 1 row affected (0.00 sec)

Records: 1? Duplicates: 0? Warnings: 0

會話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'

會話A明明沒有讀到c1=8的記錄,但就是無法插入,這就出現(xiàn)了幻讀現(xiàn)象。

如果會話A在開始事務(wù)后,

select * from test01 for update;

或者

select * from test01 lock in share mode;

那么會話B根本無法對數(shù)據(jù)做任何修改,那么這也就解決了幻讀問題。

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的mysql数据库的行级锁有几种_mysql锁之三种行级锁介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。