溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MYSQL中樂觀鎖的實現(xiàn)方法

發(fā)布時間:2021-08-03 16:11:18 來源:億速云 閱讀:127 作者:Leah 欄目:數(shù)據(jù)庫

MYSQL中樂觀鎖的實現(xiàn)方法,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

什么是MVCC

MVCC即Multi-Version Concurrency Control,中文翻譯過來叫多版本并發(fā)控制。

MYSQL中樂觀鎖的實現(xiàn)方法

MVCC是解決了什么問題

眾所周知,在MYSQL中,MyISAM使用的是表鎖,InnoDB使用的是行鎖。而InnoDB的事務分為四個隔離級別,其中默認的隔離級別REPEATABLE  READ需要兩個不同的事務相互之間不能影響,而且還能支持并發(fā),這點悲觀鎖是達不到的,所以REPEATABLE  READ采用的就是樂觀鎖,而樂觀鎖的實現(xiàn)采用的就是MVCC。正是因為有了MVCC,才造就了InnoDB強大的事務處理能力。

MVCC具體實現(xiàn)分析

InnoDB的MVCC,是通過在每行記錄后面保存兩個隱藏的列來實現(xiàn)的,這兩個列,分別保存了這個行的創(chuàng)建時間,一個保存的是行的刪除時間。這里存儲的并不是實際的時間值,而是系統(tǒng)版本號(可以理解為事務的ID),每開始一個新的事務,系統(tǒng)版本號就會自動遞增,事務開始時刻的系統(tǒng)版本號會作為事務的ID.下面看一下在REPEATABLE  READ隔離級別下,MVCC具體是如何操作的。

首先創(chuàng)建一張表:

create table yang(      id int primary key auto_increment,      name varchar(20) );

假設系統(tǒng)的版本號從1開始.

INSERT

InnoDB為新插入的每一行保存當前系統(tǒng)版本號作為版本號。***個事務ID為1:

start transaction;  insert into yang values(NULL,'yang'); insert into yang values(NULL,'long'); insert into yang values(NULL,'fei'); commit;

對應在數(shù)據(jù)中的表如下(后面兩列是隱藏列,我們通過查詢語句并看不到)

MYSQL中樂觀鎖的實現(xiàn)方法

SELECT

InnoDB會根據(jù)以下兩個條件檢查每行記錄:

  1. InnoDB只會查找版本早于當前事務版本的數(shù)據(jù)行(也就是,行的系統(tǒng)版本號小于或等于事務的系統(tǒng)版本號),這樣可以確保事務讀取的行,要么是在事務開始前已經(jīng)存在的,要么是事務自身插入或者修改過的.

  2. 行的刪除版本要么未定義,要么大于當前事務版本號(這可以確保事務讀取到的行,在事務開始之前未被刪除),  只有條件1、2同時滿足的記錄,才能返回作為查詢結(jié)果.

DELETE

InnoDB會為刪除的每一行保存當前系統(tǒng)的版本號(事務的ID)作為刪除標識.

看下面的具體例子分析: 第二個事務,ID為2:

start transaction;  select * from yang;  select * from yang;  commit;

假設1:

假設在執(zhí)行這個事務ID為2的過程中,剛執(zhí)行到(1),這時,有另一個事務ID為3往這個表里插入了一條數(shù)據(jù); 第三個事務ID為3;

start transaction; insert into yang values(NULL,'tian'); commit;

這時表中的數(shù)據(jù)如下:

MYSQL中樂觀鎖的實現(xiàn)方法

然后接著執(zhí)行事務2中的(2),由于id=4的數(shù)據(jù)的創(chuàng)建時間(事務ID為3),執(zhí)行當前事務的ID為2,而InnoDB只會查找事務ID小于等于當前事務ID的數(shù)據(jù)行,所以id=4的數(shù)據(jù)行并不會在執(zhí)行事務2中的(2)被檢索出來,在事務2中的兩條select  語句檢索出來的數(shù)據(jù)如下:

MYSQL中樂觀鎖的實現(xiàn)方法

假設2

假設在執(zhí)行這個事務ID為2的過程中,剛執(zhí)行到(1),假設事務執(zhí)行完事務3后,接著又執(zhí)行了事務4;

第四個事務:

start transaction;  delete from yang where id=1;  commit;

此時數(shù)據(jù)庫中的表如下:

MYSQL中樂觀鎖的實現(xiàn)方法

接著執(zhí)行事務ID為2的事務(2),根據(jù)SELECT  檢索條件可以知道,它會檢索創(chuàng)建時間(創(chuàng)建事務的ID)小于當前事務ID的行和刪除時間(刪除事務的ID)大于當前事務的行,而id=4的行上面已經(jīng)說過,而id=1的行由于刪除時間(刪除事務的ID)大于當前事務的ID,所以事務2的(2)select  * from yang也會把id=1的數(shù)據(jù)檢索出來.所以,事務2中的兩條select 語句檢索出來的數(shù)據(jù)都如下:

MYSQL中樂觀鎖的實現(xiàn)方法

UPDATE

InnoDB執(zhí)行UPDATE,實際上是新插入了一行記錄,并保存其創(chuàng)建時間為當前事務的ID,同時保存當前事務ID到要UPDATE的行的刪除時間。

假設3:

假設在執(zhí)行完事務2的(1)后又執(zhí)行,其它用戶執(zhí)行了事務3,4,這時,又有一個用戶對這張表執(zhí)行了UPDATE操作:

第5個事務:

start transaction;  update yang set name='Long' where id=2; commit;

根據(jù)update的更新原則:會生成新的一行,并在原來要修改的列的刪除時間列上添加本事務ID,得到表如下:

MYSQL中樂觀鎖的實現(xiàn)方法

繼續(xù)執(zhí)行事務2的(2),根據(jù)select 語句的檢索條件,得到下表:

MYSQL中樂觀鎖的實現(xiàn)方法

還是和事務2中(1)select 得到相同的結(jié)果.

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI