国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【深入淺出事務】(3):事務的隔離級別(超詳細)

zhangrxiang / 2944人閱讀

摘要:客戶端設置手動提交,修改事務隔離級別為,并且開啟事務一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交。

本質

隔離級別定義了數(shù)據(jù)庫系統(tǒng)中一個操作產生的影響什么時候以哪種方式可以對其他并發(fā)操作可見,隔離性是事務的ACID中的一個重要屬性,核心是對鎖的操作。

從數(shù)據(jù)庫系統(tǒng)角度

共享鎖(Shared Lock)

讀鎖,保證數(shù)據(jù)只能讀取,不能被修改。
如果事務A對數(shù)據(jù)M加上S鎖,則事務A可以讀記錄M但不能修改記錄M,其他事務(這里用事務B)只能對記錄M再加上S鎖,不能加X鎖,直到事務A釋放了記錄M上的S鎖,保證了其他事務(事務B)可以讀記錄M,但在事務A釋放M上的S鎖之前不能對記錄M進行任何修改。

例子: MySql 5.5 證明S鎖的特性。

數(shù)據(jù)準備

CREATE TABLE `test1` (`id`  bigint(1) NOT NULL DEFAULT 0 ,`name`  varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,PRIMARY KEY (`id`))
INSERT INTO test1 VALUES(1,1),(2,2),(3,3)

設置事務為手動提交,方便證明上訴結論(mysql默認為自動提交,執(zhí)行單句sql其實包含 開啟事務,執(zhí)行sql,提交事務,3個步驟)。

客戶端A開啟一個事務A。

客戶端A給test1表加上讀鎖。

查詢test1表原有的數(shù)據(jù)(加上S鎖后,可以讀數(shù)據(jù))。

事務A修改數(shù)據(jù)(加上S鎖后,無法修改數(shù)據(jù))。

B客戶端開啟事務B。

事務B對記錄M查詢(因為是S鎖,其他事務可以對記錄A進行select )。

事務B對記錄M加讀鎖(事務A對記錄A加上S鎖后,事務B同樣也可以對記錄A加上S鎖,證明了,mysql里的讀鎖就是S鎖,具有共享)。

事務B對記錄M加寫鎖(一直處于等待狀態(tài),被掛起,具體掛起的原因可以見:Innodb行鎖源碼學習。

事務B對記錄M修改(一直處于等待狀態(tài),被掛起)。

事務A釋放M上的S鎖。

此時事務B才得到響應。

說明了,只有釋放了讀鎖,另外一個事務才能加寫鎖,或者更新數(shù)據(jù)。

排他鎖(X 鎖)

寫鎖,若事務A對數(shù)據(jù)對象M加上X鎖,事務A可以讀記錄M也可以修改記錄M,其他事務(事務B)不能再對記錄M加任何鎖,直到事務A釋放記錄M上的鎖,保證了其他事務(事務B)在事務A釋放記錄M上的鎖之前不能再讀取和修改記錄M。

例子:Mysql 5.5,證明X鎖的特性。

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,并且開啟事務B。

事務A給記錄M加上X鎖。

事務A可以讀記錄M也可以修改記錄M。

事務B不能對記錄M加任何鎖。

事務B也不能對記錄M進行查詢和修改。

事務A釋放記錄M上的X鎖。

事務B阻塞的進程被執(zhí)行,中斷了6秒。

從程序員角度

悲觀鎖(Pessimistic[?pes??m?st?k] Lock)

對數(shù)據(jù)被外界修改保持保守態(tài)度,在整個數(shù)據(jù)處理過程中,數(shù)據(jù)處于鎖定狀態(tài),依賴于數(shù)據(jù)庫提供的鎖機制。

樂觀鎖(Optimistic[?ɑ:pt??m?st?k]Lock)

采用寬松的加鎖機制,基于數(shù)據(jù)版本記錄機制,具體做法:數(shù)據(jù)庫表增加一個"version"字段來實現(xiàn),讀取數(shù)據(jù)時,將版本號一同讀出,之后更新,對版本號加1,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫對應記錄的當前版本信息進行比對,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫的數(shù)據(jù),則予以更新,否則,被認為是過期數(shù)據(jù)。

幾個概念 丟失更新

事務A和事務B,同時獲得相同數(shù)據(jù),然后在各自的事務中修改數(shù)據(jù)M,事務A先提交事務,數(shù)據(jù)M假如為M+,事務B后提交事務,數(shù)據(jù)M變成了M++,最終結果變成M++,覆蓋了事務A的更新。

例子:

事務A 事務B
讀取X=100 讀取X=100
寫入X=X+100
事務結束X=200
寫入X=X+100
事務結束X=300(事務A的更新丟失)
臟讀

允許事務B可以讀到事務A修改而未提交的數(shù)據(jù)可能會造成了臟讀(臟讀本質就是無效的數(shù)據(jù),只有當事務A回滾,那么事務B讀到的數(shù)據(jù)才為無效的,所以這里只是可能造成臟讀,當事務A不回滾的時候,事務B讀到的數(shù)據(jù)就不為臟數(shù)據(jù),也就是有效的數(shù)據(jù),臟數(shù)據(jù)會導致以后的操作都會發(fā)生錯誤,一定要去避免,不能憑借僥幸,事務A不能百分之百保證不回滾,所以這種隔離級別很少用于實際應用,并且它的性能也不比其他級別好多少)。

例子:

事務A 事務B
寫入X=X+100(x=200)
讀取X=200(無效數(shù)據(jù),臟讀)
事務回滾X=100
事務結束X=100
事務結束
不可重復讀

不可重復讀是指在一個事務范圍中2次或者多次查詢同一數(shù)據(jù)M返回了不同的數(shù)據(jù),例如:事務B讀取某一數(shù)據(jù),事務A修改了該數(shù)據(jù)M并且提交,事務B又讀取該數(shù)據(jù)M(可能是再次校驗),在同一個事務B中,讀取同一個數(shù)據(jù)M的結果集不同,這個很蛋疼。

例子:

事務A 事務B
讀取X=100 讀取X=100
寫入X=X+100 讀取X=100
事務結束,X=200
讀取X=200(在一個事務B中讀X的值發(fā)生了變化)
事務結束
幻讀

當用戶讀取某一個范圍的數(shù)據(jù)行時,另一個事務又在該范圍內查詢了新行,當用戶再讀取該范圍的數(shù)據(jù)行時,會發(fā)現(xiàn)會有新的“幻影行”,例如:事務B讀某一個數(shù)據(jù)M,事務A對數(shù)據(jù)M增加了一行并提交,事務B又讀數(shù)據(jù)M,發(fā)生多出了一行造成的結果不一致(如果行數(shù)相同,則是不可重復讀)。

例子:

事務A 事務B
讀取數(shù)據(jù)集M(3行)
在數(shù)據(jù)集M插入一行(4行)
事務結束
讀取數(shù)據(jù)M(4行)
事務結束

在事務B里,同一個數(shù)據(jù)集M,讀到的條數(shù)不一致(新增,刪除)。

封鎖協(xié)議

在運用S鎖和X鎖對數(shù)據(jù)M加鎖的時候,需要約定一些規(guī)則,例如何時申請S鎖或者X鎖,持鎖時間,這些規(guī)則就是封鎖協(xié)議。
其中不同的封鎖協(xié)議對應不同的隔離級別。

一級封鎖協(xié)議

一級封鎖協(xié)議對應READ-UNCOMMITTED 隔離級別,本質是在事務A中修改完數(shù)據(jù)M后,立刻對這個數(shù)據(jù)M加上共享鎖(S鎖)[當事務A繼續(xù)修改數(shù)據(jù)M的時候,先釋放掉S鎖,再修改數(shù)據(jù),再加上S鎖],根據(jù)S鎖的特性,事務B可以讀到事務A修改后的數(shù)據(jù)(無論事務A是否提交,因為是共享鎖,隨時隨地都能查到數(shù)據(jù)A修改后的結果),事務B不能去修改數(shù)據(jù)M,直到事務A提交,釋放掉S鎖。

缺點:
可能會造成如下后果

丟失更新。

臟讀。

不可重復讀。

幻讀。

例子:MySql 5.5 證明一級封鎖協(xié)議會造成臟讀,不可重復讀。

A客戶端修改數(shù)據(jù)M,B客戶端設置不同的隔離級別去查看數(shù)據(jù)M,論證該級別下會發(fā)生臟讀不可重復讀(相當于客戶端A修改的數(shù)據(jù)已經寫到表里,客戶端B傳不同版本號[隔離級別],去查看數(shù)據(jù)M,所得的查詢結果也不同)。

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為read-uncommitted,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務B查詢數(shù)據(jù)M。

事務A修改其中一行數(shù)據(jù)(查詢原有基礎數(shù)據(jù),然后把id = 1 的name 修改為4 )。

事務B查看數(shù)據(jù)M,發(fā)現(xiàn)事務B讀到了事務A未提交的數(shù)據(jù),發(fā)生了臟讀。

事務A回滾。

客戶端B查詢的情況。

在同一個事務B里,查詢同一個數(shù)據(jù)M,居然2次不一樣,造成不可重復讀,其中有一次數(shù)據(jù)是無效的數(shù)據(jù),臟讀了。
假如事務A不回滾呢? 那么事務B就沒造成臟讀,不可重復讀。

例子:MySql 5.5 證明一級封鎖協(xié)議會造成更新丟失

事務A提交數(shù)據(jù)M。

事務B查詢數(shù)據(jù)M,事務B查詢的數(shù)據(jù)M,沒有臟數(shù)據(jù),并且2次結果一致,沒出現(xiàn)不可重復讀。

事務B修改數(shù)據(jù)M。

此時事務A對數(shù)據(jù)M的修改被事務B給覆蓋,造成了更新丟失

例子:MySql 5.5 證明一級封鎖協(xié)議會造成幻讀

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為read-uncommitted,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務B查詢數(shù)據(jù)M。

事務A插入一條數(shù)據(jù)。

事務B查詢數(shù)據(jù)M。

事務B第二次查詢的時候,數(shù)據(jù)M多了一行,像是發(fā)生了幻覺似的,有可能這一行是無效數(shù)據(jù)(當事務A回滾)。

二級封鎖協(xié)議

二級封鎖協(xié)議對應READ-COMMITTED隔離級別,本質是事務A在修改數(shù)據(jù)M后立刻加X鎖,事務B不能修改數(shù)據(jù)M,同時不能查詢到最新的數(shù)據(jù)M(避免臟讀),查詢到的數(shù)據(jù)M是上一個版本(Innodb MVCC快照)的。

優(yōu)點:
1.避免臟讀。

缺點:
可能會造成如下后果

丟失更新。

不可重復讀。

幻讀。

例子:MySql 5.5 證明二級封鎖協(xié)議不會造成臟讀,但是會造成不可重復讀(幻讀,丟失更新,和上面證明方式一樣,這里暫不證明了)
A客戶端修改數(shù)據(jù)M,B客戶端設置不同的隔離級別去查看數(shù)據(jù)M,論證該級別下會發(fā)生不可重復讀(相當于客戶端A修改的數(shù)據(jù)已經寫到表里,客戶端B傳不同版本號[隔離級別],去查看數(shù)據(jù)M,所得的查詢結果也不同)。

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為read-committed,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務A修改其中一行數(shù)據(jù)(查詢原有基礎數(shù)據(jù),然后把id = 1 的name 修改為4 )。

事務B查詢數(shù)據(jù)M,數(shù)據(jù)還是和之前的一樣(沒有發(fā)生臟讀),事務B讀不到了事務A未提交的數(shù)據(jù)。

事務A提交。

事務B查詢數(shù)據(jù),數(shù)據(jù)M被修改。

在同一個事務B中,查詢數(shù)據(jù)M,2次結果不一致,證明發(fā)生了不可重復讀。

三級封鎖協(xié)議

三級封鎖協(xié)議對應REPEATABLE-READ隔離級別,本質是二級封鎖協(xié)議基礎上,對讀到的數(shù)據(jù)M瞬間加上共享鎖,直到事務結束才釋放(保證了其他事務沒辦法修改該數(shù)據(jù)),這個級別是MySql 5.5 默認的隔離級別。

優(yōu)點:
1.避免臟讀。
2.避免不可重復讀。

缺點:

幻讀。

丟失更新。

例子:MySql 5.5 證明三級封鎖協(xié)議不會造成臟讀,不可重復讀(造成幻讀,丟失更新,和上面證明方式一樣,但是要在非mysql數(shù)據(jù)庫上證明,后面有解釋,這里暫不證明了)

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為repeatable-read,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務A查詢數(shù)據(jù)M。

事務B查詢數(shù)據(jù)M。

事務A更新數(shù)據(jù)M。

事務B查詢數(shù)據(jù)M,發(fā)現(xiàn)查詢的結果沒變化,避免了臟讀。

事務A提交事務。

事務B查詢數(shù)據(jù)M,還是和之前查詢的結果一樣,沒有變化,避免了不可重復讀

事務B提交事務

這個時候事務B才能查詢到最新的數(shù)據(jù)M+。

例子:MySql 5.5 證明Mysql Innodb引擎的三級封鎖協(xié)議不會造成幻讀

mysql innodb的reapetable read級別是避免了幻讀,mysql的實現(xiàn)和標準定義的RR隔離級別有差別,詳情見 how-to-produce-phantom-reads。

客戶端A設置手動提交,并且開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為repeatable-read,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務A查詢數(shù)據(jù)M。

事務B查詢數(shù)據(jù)M。

事務A對記錄M插入一條數(shù)據(jù)。

事務A提交。

事務B查看數(shù)據(jù)M。

看不到事務A新增加的一條數(shù)據(jù),說明避免了幻讀。

事務B插入一條記錄。

明明剛剛查詢到沒有ID為4的,現(xiàn)在居然插不進去,哈哈哈哈哈。

例子:MySql 5.5 證明三級封鎖協(xié)議在讀到數(shù)據(jù)的瞬間加上共享鎖,等事務結束才釋放以及三級封鎖協(xié)議會造成更新丟失

客戶端A重新開啟事務A。

客戶端B設置手動提交,修改事務隔離級別為read-committed,并且開啟事務B(一定要在開啟事務前修改事務的隔離級別,不然當前還是保持著原來的事務隔離級別,直到當前事務提交)

事務A修改數(shù)據(jù)M。

事務B也修改數(shù)據(jù)M,事務B的修改進程被掛起,因為事務A在對數(shù)據(jù)M修改后瞬間加上了共享鎖,對于其他事務只能讀。

事務A提交事務。

事務B的修改進程被喚起(等待4.98秒)。

事務B提交修改。

最終事務A,事務B查詢數(shù)據(jù)M。

事務B的修改把事務A的修改給覆蓋了,造成了更新丟失。

最強封鎖協(xié)議

最強封鎖協(xié)議對應Serialization隔離級別,本質是從MVCC并發(fā)控制退化到基于鎖的并發(fā)控制,對事務中所有讀取操作加S鎖,寫操作加X鎖,這樣可以避免臟讀,不可重復讀,幻讀,更新丟失,開銷也最大,會造成讀寫沖突,并發(fā)程度也最低。

例子:MySql 5.5 證明三級封鎖協(xié)議不會造成幻讀

客戶端A重新開啟事務A

客戶端B設置手動提交,修改隔離級別為SERIALIZABLE,并且開啟事務B。

事務A插入數(shù)據(jù),并且提交。

事務B查詢數(shù)據(jù),依然還是之前的數(shù)據(jù),避免的幻讀。

事務A修改數(shù)據(jù),被掛起。

證明了Serialization級別下寫操作是對數(shù)據(jù)M加的是X鎖。

總結

ANSI SQL 隔離級級別

隔離性 臟讀可能性 不可重復讀可能性 幻讀可能性 加鎖讀
READ-UNCOMMITTED Y Y Y N
READ-COMMITTED N Y Y N
REPEATABLE-READ N N Y N
SERIALIZABLE N N N Y

感謝您的耐心閱讀,如果您發(fā)現(xiàn)文章中有一些沒表述清楚的,或者是不對的地方,請給我留言,您的鼓勵是作者寫作最大的動力,
如果您認為本文質量不錯,讀后覺得收獲很大,不妨請我喝杯咖啡,讓我更有動力繼續(xù)寫出高質量的文章。

支付寶

微信

作 者 : @mousycoder

原文出處 : http://mousycoder.com/2016/02/19/explain-transaction-in-simple-language-3/

創(chuàng)作時間:2016-2-19

更新時間:2016-2-22

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65501.html

相關文章

  • 深入理解 MySQL ——鎖、事務與并發(fā)控制

    摘要:鎖共享鎖與排他鎖它們都是標準的行級鎖。防止任何其他事務變動的行。間隙鎖是性能和并發(fā)性之間權衡的一種折衷,用于某些特定的事務隔離級別,如級別級別,我司為了減少死鎖,關閉了鎖,使用級別。 本文首發(fā)于 vivo 互聯(lián)網(wǎng)技術微信公眾號 https://mp.weixin.qq.com/s/JF...作者:張碩 本文對 MySQL 數(shù)據(jù)庫中有關鎖、事務及并發(fā)控制的知識及其原理做了系統(tǒng)化的介紹和總...

    Dr_Noooo 評論0 收藏0
  • [靈魂拷問]MySQL面試高頻100問(工程師方向)

    摘要:黑客技術點擊右側關注,了解黑客的世界開發(fā)進階點擊右側關注,掌握進階之路開發(fā)點擊右側關注,探討技術話題作者丨呼延十排版丨團長前言本文主要受眾為開發(fā)人員所以不涉及到的服務部署等操作且內容較多大家準備好耐心和瓜子礦泉水前一陣系統(tǒng)的學習了一下也有 ...

    gyl_coder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<