日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Mysql加锁过程详解(2)-关于mysql 幻读理解

發(fā)布時間:2025/3/20 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql加锁过程详解(2)-关于mysql 幻读理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Mysql加鎖過程詳解(1)-基本知識 Mysql加鎖過程詳解(2)-關(guān)于mysql 幻讀理解 Mysql加鎖過程詳解(3)-關(guān)于mysql 幻讀理解 Mysql加鎖過程詳解(4)-select for update/lock in share mode 對事務(wù)并發(fā)性影響 Mysql加鎖過程詳解(5)-innodb 多版本并發(fā)控制原理詳解 Mysql加鎖過程詳解(6)-數(shù)據(jù)庫隔離級別(1) Mysql加鎖過程詳解(6)-數(shù)據(jù)庫隔離級別(2)-通過例子理解事務(wù)的4種隔離級別 Mysql加鎖過程詳解(7)-初步理解MySQL的gap鎖 Mysql加鎖過程詳解(8)-理解innodb的鎖(record,gap,Next-Key lock) 首先,mysql 幻讀并非是”一個事務(wù)內(nèi)進(jìn)行兩次相同操作居然得到了不一樣的結(jié)果”,因?yàn)樗静豢赡馨l(fā)生在使用了 read view / MVCC 的 RR 隔離級別下,這種幻讀的定義更適合給 Oracle,Oracle 的事務(wù)隔離只有兩級,RC 和 Serializable。然后還有很多人辯解說不可重復(fù)讀是針對某條記錄的,幻讀是針對記錄集合的,這是在自我安慰么?

這里給出 mysql 幻讀的比較形象的場景:

?

users: id 主鍵

1、T1:select * from users where id = 1;

2、T2:insert into `users`(`id`, `name`) values (1, 'big cat');

3、T1:insert into `users`(`id`, `name`) values (1, 'big cat');

?

T1 :主事務(wù),檢測表中是否有 id 為 1 的記錄,沒有則插入,這是我們期望的正常業(yè)務(wù)邏輯。

T2 :干擾事務(wù),目的在于擾亂 T1 的正常的事務(wù)執(zhí)行。

?

在 RR 隔離級別下,1、2 是會正常執(zhí)行的,3 則會報(bào)錯主鍵沖突,對于 T1 的業(yè)務(wù)來說是執(zhí)行失敗的,這里 T1 就是發(fā)生了幻讀,因?yàn)門1讀取的數(shù)據(jù)狀態(tài)并不能支持他的下一步的業(yè)務(wù),見鬼了一樣。

在 Serializable 隔離級別下,1 執(zhí)行時是會隱式的添加 gap 共享鎖的,從而 2 會被阻塞,3 會正常執(zhí)行,對于 T1 來說業(yè)務(wù)是正確的,成功的扼殺了擾亂業(yè)務(wù)的T2,對于T1來說他讀取的狀態(tài)是可以拿來支持業(yè)務(wù)的。

?

所以 mysql 的幻讀并非什么讀取兩次返回結(jié)果集不同,而是事務(wù)在插入事先檢測不存在的記錄時,驚奇的發(fā)現(xiàn)這些數(shù)據(jù)已經(jīng)存在了,之前的檢測讀獲取到的數(shù)據(jù)如同鬼影一般。

這里要靈活的理解讀取的意思,第一次select是讀取,第二次的 insert 其實(shí)也屬于隱式的讀取,只不過是在 mysql 的機(jī)制中讀取的,插入數(shù)據(jù)也是要先讀取一下有沒有主鍵沖突才能決定是否執(zhí)行插入。

不可重復(fù)讀側(cè)重表達(dá) 讀-讀,幻讀則是說 讀-寫,用寫來證實(shí)讀的是鬼影。

?

下面例子版本

SELECT VERSION();

?

?

?

例子1,讀提交

?????????????????????????????????????????????????????? a

b

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

SET AUTOCOMMIT=0;

1.不可重復(fù)讀

begin

begin

INSERT test VALUES(1,1);

?

SELECT * FROM test;

?

?

SELECT * FROM test;

?

?

?

commit

?

?

SELECT * FROM test;

?

?

?

?

COMMIT

B在一個事務(wù)的查詢的結(jié)果變了,不可重復(fù)讀

2.鎖

begin

begin

INSERT test VALUES(2,2);

?

?

SELECT * FROM test;

?

?

?

INSERT test VALUES(2,2);

?

Lock wait timeout exceeded; try restarting transaction

COMMIT

COMMIT

?

?

begin

?

INSERT test VALUES(3,3);

?

INSERT test VALUES(4,4);

?

COMMIT

?

?

BEGIN

BEGIN

SELECT COUNT(*) FROM test WHERE a>2;

?

SELECT COUNT(*) FROM test WHERE a>2;

?

??

INSERT test VALUES(5,5);

?

SELECT COUNT(*) FROM test WHERE a>2;

?

SELECT COUNT(*) FROM test WHERE a>2;

?

??

COMMIT

?

SELECT COUNT(*) FROM test WHERE a>2;

SELECT COUNT(*) FROM test WHERE a>2;

?

?

?

?

?

?

?

例子2:重復(fù)讀

?

?????????????????????????????????????????????????????? a

b

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET AUTOCOMMIT=0;

1.可重復(fù)讀

begin

begin

INSERT test VALUES(1,1);

?

SELECT * FROM test;

?

?

SELECT * FROM test;

?

?

?

commit

?

?

SELECT * FROM test;

?

?

?

?

COMMIT

?

BEGIN

?

SELECT * FROM test;

?

?

?

?

COMMIT

B在一個事務(wù)的查詢的沒變

2鎖

begin

begin

INSERT test VALUES(2,2);

?

?

SELECT * FROM test;

?

?

?

INSERT test VALUES(2,2);

?

Lock wait timeout exceeded; try restarting transaction

COMMIT

COMMIT

3(幻讀)

BEGIN

BEGIN

INSERT test VALUES(3,3);

?

SELECT * FROM test;

?

?

SELECT * FROM test;

?

?

COMMIT

?

?

SELECT * FROM test;

?

?

?

INSERT test VALUES(3,3);

?

Duplicate entry '3' for key 'PRIMARY'

?

COMMIT

?

BEGIN

?

SELECT * FROM test;

?

?

?

COMMIT

幻讀,b明明查到?jīng)]有,插入時候提示主鍵沖突,剛剛查詢沒有,出現(xiàn)幻覺?

?

?

?

?

begin

?

INSERT test VALUES(4,4);

?

COMMIT

4.可重復(fù)讀

BEGIN

BEGIN

SELECT COUNT(*) FROM test WHERE a>2;

?

SELECT COUNT(*) FROM test WHERE a>2;

?

??

INSERT test VALUES(5,5);

?

SELECT COUNT(*) FROM test WHERE a>2;

?

SELECT COUNT(*) FROM test WHERE a>2;

?

??

COMMIT

?

BEGIN

?

SELECT COUNT(*) FROM test WHERE a>2;

SELECT COUNT(*) FROM test WHERE a>2;

?

?

?

?

COMMIT

COMMIT

?

?

?

?

?

?

?

網(wǎng)上很多說范圍啊,count等等都是不對的,不用于幻讀

?

總結(jié)

以上是生活随笔為你收集整理的Mysql加锁过程详解(2)-关于mysql 幻读理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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