-
MySQL 事務隔離級別查看及修改 參考:mysql修改事務隔離級別
-
查看MySQL隔離級別
SELECT @@global.tx_isolation; SELECT @@session.tx_isolation; SELECT @@tx_isolation;
-
修改MySQL 隔離級別
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
注意:默認的行為(不帶session和global)是為下一個(未開始)事務設置隔離級別。如果你使用GLOBAL關鍵字,語句在全局對從那點開始創建的所有新連接(除了不存在的連接)設置默認事務級別。你需要SUPER權限來做這個。使用SESSION 關鍵字為將來在當前連接上執行的事務設置默認事務級別。 任何客戶端都能自由改變會話隔離級別(甚至在事務的中間),或者為下一個事務設置隔離級別。
-
-
MySQL 事務的隔離級別及每種隔離級別存在的問題 參考:深入理解MySQL的四種隔離級別及加鎖實現原理
-
事務的四大特性
-
原子性 ( Atomicity )
事務是數據庫的邏輯工作單位,事務中包含的各操作要么都做,要么都不做
-
一致性 ( Consistency )
務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。也就是說數據庫中只包含成功事務提交的結果
-
隔離性 ( Isolation )
並發執行的各個事務之間不會互相干擾
-
持久性 ( Durability )
指一個事務一旦提交,它對數據庫中的數據的改變就應該是永久性的
-
-
事務的隔離級別
-
Read Uncommitted(讀未提交)
所有事務都可以看到其他未提交事務的執行結果,會產生臟讀(讀取未提交的數據)
-
Read Committed(讀提交)
一個事務只能看見已經提交事務所做的改變,會產生不可重復讀問題
-
Repeatable Read(可重讀)
這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在並發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)
-
Serializable(串行化)
這是最高的隔離級別,讀加共享鎖,寫加排他鎖,讀寫互斥,從而解決幻讀問題。在這個級別,可能導致大量的超時現象和鎖競爭,如果業務並發的特別少,同時又要求數據及時可靠的話,可以使用。
-
-
隔離級別產生的問題
- 臟讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由於某些原因,前一個RollBack了操作,則后一個事務所讀取的數據不正確了
- 不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。
- 幻讀(Phantom Read):在一個事務的兩次查詢中數據不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。
讀未提交 可能會導致 臟讀、不可重復讀、幻讀
讀提交 可能會導致 不可重復讀、幻讀
可重讀 可能會導致 幻讀
-
事務的加鎖機制
-
一次封鎖 和 兩段鎖協議
-
一次封鎖,在方法的開始階段,已經預先知道會用到哪些數據,然后全部鎖住,在方法運行之后,再全部解鎖。這種方式不會產生循環死鎖的問題,但數據庫中在事務開始階段,數據庫並不知道會用到哪些數據,所以在數據庫中不適用。
-
兩段鎖協議
將事務分為 加鎖階段 和 解鎖階段
-
加鎖階段,在這個階段只能進行加鎖,讀操作加共享鎖,寫操作加排它鎖,有時候刪除和插入操作會加區間鎖
-
解鎖階段,當事務釋放了一個封鎖以后,事務進入解鎖階段,在該階段只能進行解鎖操作不能再進行加鎖操作。
事務 加鎖/解鎖處理 begin; insert into test ..... # 加insert對應的鎖 update test set... # 加update對應的鎖 delete from test .... # 加delete對應的鎖 commit; # 事務提交時,同時釋放 insert、update、delete對應的鎖
這種方式雖然無法避免死鎖(當事務A先需要資源1然后需要資源2, 事務B 先需要資源2然后需要資源1),但是兩段鎖協議可以保證事務的並發調度是串行化
-
-
-
悲觀鎖和樂觀鎖
-
悲觀鎖:往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)。
在悲觀鎖的情況下,為了保證事務的隔離性,就需要一致性鎖定讀。讀取數據時給加鎖,其它事務無法修改這些數據。修改刪除數據時也要加鎖,其它事務無法讀取這些數據。
在MySQL InnoDB 中 RR 級別下,悲觀鎖加的是 next-Key鎖
-
樂觀鎖:基於數據版本( Version )記錄機制實現。為數據增加一個版本標識,讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大於數據庫表當前版本號,則予以更新,否則認為是過期數據。
-
-
MVCC 的實現
在InnoDB中,會在每行數據后添加兩個額外的隱藏的值來實現MVCC,這兩個值一個記錄這行數據何時被創建,另外一個記錄這行數據何時過期(或者被刪除)。 在實際操作中,存儲的並不是時間,而是事務的版本號,每開啟一個新事務,事務的版本號就會遞增。 在可重讀Repeatable reads事務隔離級別下: SELECT時,讀取創建版本號<=當前事務版本號,刪除版本號為空或>當前事務版本號。 INSERT時,保存當前事務版本號為行的創建版本號。 DELETE時,保存當前事務版本號為行的刪除版本號。 UPDATE時,插入一條新紀錄,保存當前事務版本號為行創建版本號,同時保存當前事務版本號到原來刪除的行。 通過MVCC,雖然每行記錄都需要額外的存儲空間,更多的行檢查工作以及一些額外的維護工作,但可以減少鎖的使用,大多數讀操作都不用加鎖,讀數據操作很簡單,性能很好,並且也能保證只會讀取到符合標准的行,也只鎖住必要行。
在MVCC中 為了減少鎖處理(包括等待其它鎖)的時間,提升並發能力,引入了快照讀(讀取歷史數據)的概念,使得select不用加鎖。
寫(當前讀):為了幻讀問題,MySQL事務使用了Next-Key鎖。Next-Key鎖是行鎖和GAP(間隙鎖)的合並,行鎖防止別的事務修改或刪除,GAP鎖防止別的事務新增。
-
-
注:如需轉載,請注明出處:https://www.cnblogs.com/zhuchenglin/p/12709749.html