mysql-repeatable read 可重復讀隔離級別-幻讀實例場景


本文詳解 repeatable read 可重復讀 隔離級別產生的影響(幻讀)

-- SERIALIZABLE serializable 序列化 ;一個個事務排成序列的形式。事務一個挨一個執行,等待前一個事務執行完,后面的事務才可以順序執行

-- REPEATEABLE READ repeatable read 可重復讀;安全上不如serializable,但是性能上比serializable強很多,但會造成幻讀。隔離級別:導致幻讀,同時開啟兩個事務,事務A和事務B,當事務A修改了數據,並且提交了,事務B此時查看不到事務A已經提交了的數據,這樣保持事務B先后兩次查詢結果的一致性,當事務B執行update操作的時候,是可以更改事務A提交了的update,insert數據,執行過update操作之后再次select發現數據前后查詢不一致!(幻讀)
-- READ COMMITED read committed 提交的可讀;(oracle默認)
-- READ UNCOMMITED read uncommitted 未提交的可讀;(mysql 默認)別的事務可以查看的到使用 當前事務還沒提交的 數據;會 臟讀,幻讀,不可重復讀。
-- 幻讀:一個事務的查詢中查詢兩次數據,數據不一致!同時開啟事務A,事務B。事務A查詢一張表中的數據后,事務B修改update了事務A查詢的表並做了提交,事務A再次查詢這張表,發現數據的不一致!

首先說明:mysql的innodb存儲引擎默認的隔離級別就是 repeatable read 可重復讀

1.首先開啟兩個mysql連接,分別開啟兩個事務A,事務B;兩個事務分別查詢 software 表的數據,此時數據顯示一致的。

1)事務A

 2)事務B

3)事務A此時修改了sid = 4 的version ,select 可以查看當前修改的結果,但是還沒有提交commit!

4)事務B select * from software;查看software是否有修改,發現沒有被修改!

5)事務A,做commit提交;並查看select * from software; 

6)事務B,在 5)中事務A做了提交之后,事務B此時是查看不到 事務A對 sid = 4 的version做出的修改的!

7)事務B,執行update software set version = version + 1; 並執行select * from software; 查看,發現出現了幻讀。

sid = 4 的 version 是在事務A提交后的結果 version = 44 上進行了 + 1 的操作!

總結:幻讀的實現場景:事務B先后查詢software表出現的結果,與預想的update 后 version+1 的結果出現了不一致。

另外:事務A,事務B同時對software表的同一條記錄做修改,后執行的事務可能會執行失敗,此時可能會發生行鎖的lock情況,執行不成功。后執行的事務必須等待先執行的事務先commit或者rollback,才能對這同一條要修改的記錄作出修改;

如:事務A與事務B同時開啟,事務A先對sid = 4 的version做修改update。事務B再修改sid的version

1>事務A,此時事務A還沒有作出提交commit。

2>事務B 報錯ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

發生了行鎖,sid= 4 的記錄被事務A鎖住了,等待事務A作出提交commit或rollback超時。

3>當事務A作出了commit之后,事務B在執行update如下,就可以成功update了

 


免責聲明!

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



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