mysql鎖(七)丟失更新,臟讀,不可重復讀,幻讀

****這些問題的出現的原因****
之所以出現更新丟失,臟讀,和不可重復讀,幻讀,是因為當兩個事務同時進行的時候,兩者之間互相不知道對方的存在,對自身所處的環境過分樂觀,從而沒有對操作的數據做一定的保護處理,最終導致一些問題的出現。

而我們之前介紹的隔離級別,其實就是通過一定的機制和鎖來避免這樣的問題,從而讓我們的并發事務可以正常的進行。


****丟失更新問題****



上圖中,由于事務A與事務B互相不知道對方的存在,因此導致了悲劇的發生。
如果避免這個問題?
通過樂觀鎖可以解決這個問題,在T9階段,事務A進行更新余額操作的時候,SQL修改如下如下update table set amount=1100 where id=xxx **** and amount=1000****,通過加上一個金額的判斷,這樣的話,如果更改之前數據沒有修改則執行成功,否則執行失敗回滾。


****臟讀****
讀取的數據是不正確的數據,即為臟讀。
mysql 中一個事務讀取了另一個未提交的并行事務寫的數據,那這個讀取就是臟讀。



圖中,事務A在T4階段讀取賬戶金額為110,這個數據就屬于臟數據,因為這個數據是事務B撤銷掉的數據,所以如果事務A使用數據110進行后續的賬戶操作,就會引發問題。
如果避免這個問題?
read commited及以上隔離級別設定,一個事務只能讀取另一個事務已經提交的數據,就避免了上面的臟讀現象。


****不可重復讀****
不可重復讀,顧名思義,即不能多次重復去讀,因為讀出來的結果不一樣,因此認為存在不可重復讀的問題。

read commited下設定,一個事務只能讀取另一個事務已經提交的數據,這就會出現不可重復讀的問題。

repeatable read及以上級別設定,一個事務里,對數據的多次查詢都是讀取的一個,無論該數據在中途是否被其他事務修改過,因此也就避免了不可重復讀的問題。


****幻讀****



上圖中,事務A一開始查詢沒有數據,但是插入記錄失敗,提示主鍵沖突,這種查詢明明沒有,插入卻提示已經存在的現象,叫做幻讀。
幻讀和不可重復讀類似,即兩次讀取的結果不一致,兩者的不同點在于,不可重復讀針對數據的修改造成的讀不一致,而幻讀針對數據的插入和刪除造成的讀不一致,如同發生幻覺一樣。

Repeatable read及以上級別通過間隙鎖來防止幻讀的出現,即鎖定特定數據的前后間隙讓數據無法被插入

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容