溫馨提示×

溫馨提示×

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

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

MySQL事務隔離級別

發布時間:2020-06-25 19:35:28 來源:網絡 閱讀:363 作者:nineteens 欄目:MySQL數據庫

  四類隔離級別

  ??SQL標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發處理,并擁有更低的系統開銷。

  Read Uncommitted(讀取未提交內容)

  ??在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用于實際應用,因為它的性能也不比其他級別好多少。讀取未提交的數據,也被稱之為臟讀(Dirty Read)。

  舉例:

  ??公司發工資了,把50000元打到我的賬號上,但是該事務并未提交,而我正好去查看賬戶,發現工資已經到賬,是50000元整,非常高興??墒遣恍业氖?,領導發現發給的工資金額不對,是2000元,于是迅速回滾了事務,修改金額后,將事務提交,最后我實際的工資只有2000元,空歡喜一場。

  ??臟讀是兩個并發的事務,“事務A:領導發工資”、“事務B:我查詢工資賬戶”,事務B讀取了事務A尚未提交的數據。

  ??當隔離級別設置為Read uncommitted時,就可能出現臟讀,如何避免臟讀,請看下一個隔離級別。

  Read Committed(讀取提交內容)

  ??這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結果。

  舉例:

  ??我拿著工資卡去消費,系統讀取到卡里確實有2000元,而此時老婆也正好在網上轉賬,把工資卡的2000元轉到她賬戶,并在我之前提交了事務,當我扣款時,系統檢查到工資卡已經沒有錢,扣款失敗,十分納悶,明明卡里有錢,為何…

  ??不可重復讀是兩個并發的事務,“事務A:消費”、“事務B:老婆網上轉賬”,事務A事先讀取了數據,事務B緊接了更新了數據,并提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。

  ??當隔離級別設置為Read committed時,避免了臟讀,但是可能會造成不可重復讀。

  Repeatable Read(可重讀)

  ??這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。

  舉例:

  ??當隔離級別設置為Repeatable read時,可以避免不可重復讀。當我拿著工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),我老婆就不可能對該記錄進行修改,也就是不能在此時轉賬。無錫人流手術多少錢 http://mobile.chnk120.com/

  ??雖然Repeatable read避免了不可重復讀,但還有可能出現幻讀。例如:老婆工作在銀行部門,她時常通過銀行內部系統查看我的信用卡消費記錄。有一天,她正查詢到我當月信用卡的總消費金額(select sum(amount) from transaction where month = 本月)為80元,而我此時正好在外面吃完大餐后在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction … ),并提交了事務,隨后老婆將我的當月信用卡消費的明細打印到A4紙上,卻發現消費總額為1080元,老婆很詫異,以為出現了幻覺,幻讀就這樣產生了。

  Serializable(可串行化)

  ??這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

  隔離級別與一致性

  ??這四種隔離級別采取不同的鎖類型來實現,若讀取的是同一個數據的話,就容易發生問題。例如:

  ?? 臟讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由于某些原因,前一個RollBack了操作,則后一個事務所讀取的數據就會是不正確的。

  ?? 不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。

  ?? 幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。

  在MySQL中,實現了這四種隔離級別,分別有可能產生問題如下所示:

  隔離級別  臟讀  不可重復讀  幻讀

  讀未提交(Read Uncommitted)  √  √  √

  讀已提交(Read Committed)  ×  √  √

  可重復讀(Repeatable Read)  ×  ×  √

  可串行化(Serializable)  ×  ×  ×

  總結:

  Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生。

  Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。

  Read committed (讀已提交):可避免臟讀的發生。

  Read uncommitted (讀未提交):最低級別,任何情況都無法保證。

  ??以上四種隔離級別最高的是Serializable級別,最低的是Read uncommitted級別,級別越高,執行效率就越低。像Serializable這樣的級別,就是以鎖表的方式(類似于Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時選用何種隔離級別應該根據實際情況。在MySQL數據庫中默認的隔離級別為Repeatable read (可重復讀)。

  ??在MySQL數據庫中,支持上面四種隔離級別,默認的為Repeatable read (可重復讀);而在Oracle數據庫中,只支持Serializable (串行化)級別和Read committed (讀已提交)這兩種級別,其中默認的為Read committed級別。


向AI問一下細節

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

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女