1. 程式人生 > >[MySQL] mysql的事務隔離和幻讀和死鎖問題

[MySQL] mysql的事務隔離和幻讀和死鎖問題

查看 復讀 原子性 zab 串行 一行 幻讀 serializa 錯誤

1.系統要通過嚴格的ACID測試,ACID表示原子性/一致性/隔離性/持久性
原子性:一個事務必須被視為一個不可分割的最小工作單元
一致性:數據庫總是從一個一致性的狀態轉換到另外一個一致性的狀態
隔離性:通常來說一個事務所做的修改在最終提交以前對其他事務是不可見的
持久性:一旦事務提交,則其所做的修改就會永久保存到數據庫中


2.sql標準中定義了四種隔離,較低級別的隔離可以執行更高的並發,開銷也更低

READ UNCOMMITTED 未提交讀,事務中的修改還沒提交,其他事務就可以看到,這也是臟讀,一般不會用
READ COMMITED 提交讀,大多數的默認級別,在提交之前,所做的任何修改對其他事務都是不可見的

REPEATABLE READ 可重復讀,解決了臟讀的問題,保證了同一個事務中多次讀取同一個記錄結果一致,但是還是會有幻讀問題
SERIALIZABLE 可串行化,避免幻讀問題,每一行都加鎖

3.事務的隔離級別下的問題
臟讀:事務可以讀取別的事務未提交的臟數據
不可重復讀:事務不可以讀取未提交的數據,但是如果在另一個事務修改並提交了數據,此時可以讀取到,同一事務兩次相同的select結果可能會不同
幻讀:事務不可以讀取未提交的,也不能讀取修改提交的,但是當另一個事務插入新數據提交後,我本次事務有時會插入沖突,或者更新時更新的數據多了
加鎖:強制串行執行,鎖開銷比較大

4.查看隔離級別:
select @@global.tx_isolation, @@tx_isolation;

| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ

5.幻讀問題

開啟事務,查詢數據

技術分享圖片

此時有另外的會話插入新數據

技術分享圖片

再次查詢新數據不會出現,但是插入時會報錯

技術分享圖片

6.mysql 死鎖:
1.兩個或多個事務在同一個資源上相互占用,並請求鎖定對方占用的資源,導致惡性循環
2.解決這種問題,檢測到死鎖的循環依賴,立即返回一個錯誤
3.時間達到了鎖等待超時限定,放棄鎖請求
4.將持有最少行級寫鎖的事務回滾

5.如果是真正的數據沖突,這種是很難避免的,必須要提交或回滾其中一個事務

開啟事務,更新數據,還沒提交

技術分享圖片

此時另外的會話執行同樣的更新,會阻塞,一段時間和會報錯

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

技術分享圖片

[MySQL] mysql的事務隔離和幻讀和死鎖問題