mysql事務(wù)

一、為什么需要事務(wù)

比如,在銀行業(yè)務(wù)中,有一條記賬原則,即有借有貸,借貸相等。為了保證這種原則,每發(fā)生一筆銀行業(yè)務(wù),就必須確保會計賬目上借方科目和貸方科目至少各記一筆,并且這兩筆賬要么同時成功,要么同時失敗。如果出現(xiàn)只記錄了借方科目,或者只記錄了貸方科目的情況,就違反了記賬原則。會出現(xiàn)記錯賬的情況。

MySQL 為了解決此類問題,提供了事務(wù)。事務(wù)可以將一系列的數(shù)據(jù)操作捆綁成一個整體進行統(tǒng)一管理,如果某一事務(wù)執(zhí)行成功,則在該事務(wù)中進行的所有數(shù)據(jù)更改均會提交,成為數(shù)據(jù)庫中的永久組成部分。

如果事務(wù)執(zhí)行時遇到錯誤,則就必須取消或回滾。取消或回滾后,數(shù)據(jù)將全部恢復(fù)到操作前的狀態(tài),所有數(shù)據(jù)的更改均被清除。

二、事務(wù)的四大特性

事務(wù)的四大特性為原子性,一致性,隔離性,持久性,其概念分別如下:

⑴ 原子性(Atomicity)

  原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾,因此事務(wù)的操作如果成功就必須要完全應(yīng)用到數(shù)據(jù)庫,如果操作失敗則不能對數(shù)據(jù)庫有任何影響。

⑵ 一致性(Consistency)

  一致性是指事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另一個一致性狀態(tài),也就是說一個事務(wù)執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài)。

⑶ 隔離性(Isolation)

  隔離性是當(dāng)多個用戶并發(fā)訪問數(shù)據(jù)庫時,比如操作同一張表時,數(shù)據(jù)庫為每一個用戶開啟的事務(wù),不能被其他事務(wù)的操作所干擾,多個并發(fā)事務(wù)之間要相互隔離。

  即要達到這么一種效果:對于任意兩個并發(fā)的事務(wù)T1和T2,在事務(wù)T1看來,T2要么在T1開始之前就已經(jīng)結(jié)束,要么在T1結(jié)束之后才開始,這樣每個事務(wù)都感覺不到有其他事務(wù)在并發(fā)地執(zhí)行。

⑷ 持久性(Durability)

  持久性是指一個事務(wù)一旦被提交了,那么對數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久性的,即便是在數(shù)據(jù)庫系統(tǒng)遇到故障的情況下也不會丟失提交事務(wù)的操作。

三、事務(wù)存在的問題

臟讀

臟讀指的是讀到了其他事務(wù)未提交的數(shù)據(jù),未提交意味著這些數(shù)據(jù)可能會回滾,也就是可能最終不會存到數(shù)據(jù)庫中,也就是不存在的數(shù)據(jù)。讀到了并一定最終存在的數(shù)據(jù),這就是臟讀。

不可重復(fù)讀

對比可重復(fù)讀,不可重復(fù)讀指的是在同一事務(wù)內(nèi),不同的時刻讀到的同一批數(shù)據(jù)可能是不一樣的,可能會受到其他事務(wù)的影響,比如其他事務(wù)改了這批數(shù)據(jù)并提交了。通常針對數(shù)據(jù)更新(UPDATE)操作。

可重復(fù)讀

可重復(fù)讀指的是在一個事務(wù)內(nèi),最開始讀到的數(shù)據(jù)和事務(wù)結(jié)束前的任意時刻讀到的同一批數(shù)據(jù)都是一致的。通常針對數(shù)據(jù)更新(UPDATE)操作。

幻讀

幻讀是針對數(shù)據(jù)插入(INSERT)操作來說的。假設(shè)事務(wù)A對某些行的內(nèi)容作了更改,但是還未提交,此時事務(wù)B插入了與事務(wù)A更改前的記錄相同的記錄行,并且在事務(wù)A提交之前先提交了,而這時,在事務(wù)A中查詢,會發(fā)現(xiàn)好像剛剛的更改對于某些數(shù)據(jù)未起作用,但其實是事務(wù)B剛插入進來的,讓用戶感覺很魔幻,感覺出現(xiàn)了幻覺,這就叫幻讀。

事務(wù)隔離就是為了解決上面提到的臟讀、不可重復(fù)讀、幻讀這幾個問題

四、事務(wù)的隔離級別

Read Uncommitted(未提交讀)

在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。該級別用的很少。

Read Committed(提交讀)

這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變,換句話說就是事務(wù)提交之前對其余事務(wù)不可見。這種隔離級別也支持不可重復(fù)讀(Nonrepeatable Read),因為同一事務(wù)的其他實例在該實例處理其間可能會有新的commit,所以同一select查詢可能返回不同結(jié)果。

Repeatable Read(可重復(fù)讀)

這是MySQL的默認事務(wù)隔離級別,它確保同一事務(wù)的多個實例在并發(fā)讀取數(shù)據(jù)時,會看到同樣的數(shù)據(jù)行。不過理論上,這會導(dǎo)致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時,會發(fā)現(xiàn)有新的“幻影” 行。

Serializable(可串行化)

這是最高的隔離級別,它強制事務(wù)都是串行執(zhí)行的,使之不可能相互沖突,從而解決幻讀問題。換言之,它是在每個讀的數(shù)據(jù)行上加上共享鎖。在這個級別,可能導(dǎo)致大量的超時現(xiàn)象和鎖競爭。

五、可重復(fù)讀實現(xiàn)原理MVCC

https://blog.csdn.net/sanyuesan0000/article/details/90235335

六、當(dāng)前讀和快照讀

當(dāng)前讀

常見的delete,insert,update,還有select for update,select in share mode都是當(dāng)前讀.

每次讀取的都是當(dāng)前最新的數(shù)據(jù),但是讀的時候不允許寫,寫的時候也不允許讀。

實現(xiàn):Mysql實現(xiàn)當(dāng)前讀是通過共享鎖+排他鎖+Next-Key Lock實現(xiàn)的。

每次對行數(shù)據(jù)進行讀取的時候,加共享鎖。此時就不允許修改,但是允許其他事務(wù)讀取,所以每次都可以讀到最新的數(shù)據(jù)。

每次對行數(shù)據(jù)進行修改的時候,加排他鎖,不允許其他事務(wù)讀取和修改。這種情況下其他事務(wù)讀取的數(shù)據(jù)也一定是最新的數(shù)據(jù)。

每次對范圍行數(shù)據(jù)進行讀取的時候,對這個范圍加一個范圍共享鎖。

每次對范圍行數(shù)據(jù)進行修改的時候,對這個范圍加一個范圍排它鎖。

快照讀

普通的select就是快照讀.

讀寫不沖突,每次讀取的是快照數(shù)據(jù)。

實現(xiàn):mysql中的快照讀是通過MVCC+undolog實現(xiàn)的。

當(dāng)我們對記錄做了變更操作時,就會產(chǎn)生undo記錄,undo記錄中存儲的是老版數(shù)據(jù),當(dāng)一個舊的事務(wù)需要讀取數(shù)據(jù)時,為了能夠讀取到老版本的數(shù)據(jù),需要順著undo列找到滿足其可見性的記錄,這個找滿足可見行的記錄依賴。就是說每次都是讀取undolog中的數(shù)據(jù)。


Repeatable Read 在事務(wù)發(fā)生第一次讀的時候選定所要讀取的數(shù)據(jù)行的版本,整個事務(wù)都讀取這一個版本的數(shù)據(jù)行,所以可以重復(fù)讀,每次讀取的數(shù)據(jù)都一致。

Read Committed 在事務(wù)中每次讀操作都是讀取最新的行數(shù)據(jù)版本,而這最新的數(shù)據(jù)行版本很可能是某個事務(wù)進行了修改操作后提交的,所以可能會發(fā)生多次讀取同一行數(shù)據(jù),但是前后讀取的數(shù)據(jù)不一致的情況。這就是不可重復(fù)讀現(xiàn)象,所以提交讀不能避免不可重復(fù)度現(xiàn)象。

https://blog.csdn.net/Crazy_xym/article/details/104827353

https://blog.csdn.net/qq_42651904/article/details/110622818

參考:

https://blog.csdn.net/weixin_44234912/article/details/109068006

https://www.cnblogs.com/cnbk/p/13043872.html

https://zhuanlan.zhihu.com/p/117476959

https://blog.csdn.net/sanyuesan0000/article/details/90235335

https://blog.csdn.net/Crazy_xym/article/details/104827353

https://blog.csdn.net/qq_42651904/article/details/110622818

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容