mysql中的事務處理


  關鍵詞:一致性、隔離性、幻讀、

  前言:

    假設此時事務A事務B同時執行。


一、事務的定義&&特性:

1、定義:

  對數據庫進行的一組操作序列,同時這組操作序列必須滿足ACID四個特性。

2、事務的特性:

  ①原子性(Atomic):指對數據庫的操作要么全部一起執行,要么全部不執行;
  ②一致性(Consistency):指的是事務必須保證系統從某一個一致性狀態轉變為另外一個一致性狀態。;
  ③隔離性(Isolation):並發事務執行過程中,不同的事務之間相互隔離執行的一個特性;
  ④持久性(Durability):事務提交后,對系統的影響是永久的。 

  詳見:https://blog.csdn.net/chosen0ne/article/details/10036775

二、事務的一致性與隔離性的分析:

1、一致性:

(1)定義:

  事務保證系統從某一個一致性狀態轉變為另外一個一致性狀態。

(2)分析:

  老梁向小梁轉賬,假設轉賬之前這大小梁的錢加起來總共是10000,那么老梁向小梁轉賬之后,不管這兩個賬戶怎么轉,老梁的錢和小梁的錢加起來的總額必須還是10000,這個就是事務的一致性。

2、隔離性:

(1)定義:

  並發事務執行過程中,不同的事務之間相互隔離執行的一個特性。

(2)隔離級別:

  ①讀未提交(Read Uncommitted):在事務A執行過程中,可以讀取事務B未提交的數據;
  ②讀提交(Read Committed):在事務A執行過程中,只能讀取事務B提交的最新的內容;
  ③可重復讀(Repeated Read):在事務A執行過程中,沒辦法讀取事務B更新的數據(不管是提交還是未提交的),只有在事務A執行完畢的時候才能夠讀取到事務B的更新;
  ④串行化(Serialization):在事務A執行過程中,事務B沒辦法進行任何操作,只能等待事務A執行完再執行事務B。

  事務的隔離強度:Read Uncommitted < Read Committed < Repeated Read < Serialization

  詳見:https://baijiahao.baidu.com/s?id=1629344395894429251&wfr=spider&for=pc  

(3)並發事務執行過程中會產生的三個問題: 

  ①臟讀:指的是執行事務A時,讀取事務B未提交的數據,但在這之后事務B進行了回滾操作,導致剛才事務A讀取的數據時無效的。此時讀取了“臟”的數據,所以稱為臟讀。
  ②不重復讀:指的是執行事務A時,如果事務B不斷commit,那么事務A每次都可以讀到事務B提交的最新的數據。這就導致了事務A先后兩次讀到的數據結果會不一致,也就是說每次讀的數據都是不重復的。所以稱為不重復讀。
  ③幻讀:指的是執行事務A時,事務A只能夠讀取事務B第一次commit的內容;如果在事務A執行過程中,事務B又commit了修改,那么是不會影響到事務A。但是當事務A執行完,也就是在它commit的時候,就會發現原來數據竟然已經被事務B更改了。這樣子就產生了幻讀的現象。

(4)"隔離級別"與"產生的問題"的詳細分析:

不同隔離級別會產生的問題:

  • Read Uncommitted級別:臟讀、不重復讀、幻讀
  • Read Committed級別:不重復讀、幻讀
  • Repeated Read級別:幻讀
  • Serialization級別:都不會產生
②Repeatable Read級別 && 幻讀:
  數據庫的四種隔離級別在不同數據庫中的實現是不同的。在mysql的innodb引擎中,在實現Repeatable Read這個隔離級別的時候,已經解決了幻讀的問題了。(雖然SQL標准中沒有要求解決幻讀,但是innodb中通過使用MVCC+間隙鎖解決了幻讀問題。) 幻讀問題解決參見:MVCC--多版本並發控制機制中的第7點的分析

(5)不同隔離級別下的讀操作和寫操作下的讀和寫操作的區別:

前提:重點分析Repeatable Read級別和Serialization級別;innodb引擎。

a、Repeatable Read級別:
  • 事務A寫:會加X鎖,此時事務B肯定不能進行任何操作;
  • 事務A讀:對於快照讀,通過MVCC來控制增刪改查等操作;對於當前讀,除了對當前記錄加鎖之外還需要結合gap鎖來對記錄的間隙加鎖以保證了事務B只能讀取數據而不能進行其他寫操作。
b、Serialization級別:
  • 不管是讀還是寫,都是串行化的。事務A在操作的時候,事務B只能等待。

(6)如何實現Read Commit隔離級別下的效果:

①效果:當前事務只能讀其他事務已提交的記錄:

②分析:

  InnoDB 支持行鎖,進行寫操作時加的是行級中的排他鎖,那么當其他事務訪問另一個正在update (除select操作外其他操作本質上都是寫操作)同一條記錄的事務時,事務的讀操作會被阻塞。所以只能等到記錄(其實是索引上的鎖)上的排他鎖釋放后才能進行訪問,也就是另一個事務提交之后才能夠訪問。這樣確實就實現read commited隔離級別的效果。

 
 

參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM