測試一下MySQL四種隔離級別都做了什麼

Yfeil發表於2024-03-28

準備工作:

一個表:

兩條事務 ,每條事務有兩條相同sql,update值改成A、B用作區分:

1.讀未提交

1.1測試髒讀:事務A執行update操作,不提交,事務B執行select查詢結果。

期望:按照網上所說,應該會產生髒讀問題,查詢到未提交的值,即name = "事務A"。

測試結果:和期望一致。

1.2繼續測試,新建個事務C,使用可重複讀級別能讀到什麼?

期望:應該解決了髒讀問題所以,不會讀到 "name=事務A",而是 123.

結果:name = "123",完全符合。

1.3事務C執行update,看看事務A的查詢結果

結果如下:update直接被行鎖阻塞了

結論:即便是讀未提交級別 執行update後也會給行 加寫鎖。

1.4中斷事務C,回滾事務A,事務B執行select結果

結果:name = "123"

2.讀已提交

2.1測試髒讀:事務A執行update,不提交,事務B執行select

期望:name = "123"

結果:完全一致,解決了髒讀問題。

測試

2.2測試不可重複讀:事務A先查詢,然後事務B更新並提交,事務A再查詢。

期望:name = "事務B"

結果:完全符合,重複查指定欄位會讀到別的事務提交的值。

3.可重複讀

1.1測試不可重複讀:事務A先查詢,然後事務B更新並提交,事務A再查詢。

期望:應該和第一次查結果一致name = "123",不受事務B提交的影響。

結果:完全一致,重複讀同一欄位不會受其他事務提交的影響。

1.2擴充套件測試:事務A 查詢where 先改成 id=2並執行,然後事務B更新並提交,事務A改回 id =1 執行查詢,檢視結果。

期望:name = "事務B",由於事務A第一次查的是id=2,不是1,所以不應該快取到1的值,事務A第一次查1是在事務B修改並提交後,預測查到的是新值。

結果:name = "123",具體原因未知,猜測 select 後相近的記錄被快取了,於是又測一次,第一次查詢的表 改成其他表,結果仍然是123。

原因猜測:事務A執行第一條sql後的時間被記錄為 快照點,在事務A要讀取某欄位時,系統會根據日誌,查詢某欄位在快照點之後的修改記錄,並逆向還原。

經百度,mysql存在 快照讀 機制,可百度進行了解。

1.3幻讀測試:事務A執行select * from user;事務B插入一條新資料,事務A再次select

期望:6條資料,表原有5條資料,插入一條後,由於存在幻讀,所以應該查到6條。

結果:還是5條資料,

原因:還是和 mysql 快照讀機制有關。

4.序列化

待更新。。

相關文章