資料庫的資料的不可讀,髒讀,幻讀和丟失更新

2021-08-04 22:46:28 字數 1773 閱讀 6476

1.出現的原因:

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

丟失更新問題:

上圖中,由於事務a與事務b互相不知道對方的存在,因此導致了悲劇的發生。

如果避免這個問題?

通過樂觀鎖可以解決這個問題,在t5階段,事務a進行更新餘額操作的時候,sql修改如下如下update table set amount=1100 where id=***and amount=1000,通過加上乙個金額的判斷,這樣的話,如果更改之前資料沒有修改則執行成功,否則執行失敗回滾。

髒讀 讀取的資料是不正確的資料,即為髒讀。

mysql 中乙個事務讀取了另乙個未提交的並行事務寫的資料,那這個讀取就是髒讀。

圖中,事務a在t4階段讀取賬戶金額為110,這個資料就屬於髒資料,因為這個資料是事務b撤銷掉的資料,所以如果事務a使用資料110進行後續的賬戶操作,就會引發問題。

如果避免這個問題?

read commited及以上隔離級別設定,乙個事務只能讀取另乙個事務已經提交的資料,就避免了上面的髒讀現象。

不可重複讀

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

read commited下設定,乙個事務只能讀取另乙個事務已經提交的資料,這就會出現不可重複讀的問題。

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

上圖中,事務a一開始查詢沒有資料,但是插入記錄失敗,提示主鍵衝突,這種查詢明明沒有,插入卻提示已經存在的現象,叫做幻讀。

幻讀和不可重複讀類似,即兩次讀取的結果不一致,兩者的不同點在於,不可重複讀針對資料的修改造成的讀不一致,而幻讀針對資料的插入和刪除造成的讀不一致,如同發生幻覺一樣。

repeatable read及以上級別通過間隙鎖來防止幻讀的出現,即鎖定特定資料的前後間隙讓資料無法被插入 

關於樂觀鎖和悲觀鎖

悲觀鎖(pessimistic lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖(optimistic lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,

像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了效能,所以這種情況下用悲觀鎖就比較合適。

資料庫資料髒讀幻讀不可重複度的解決

要想解決資料的的髒讀幻讀和不可重複讀,首先要了解事務的隔離級別 一致性 隔離性 永續性 原子性 當執行失敗,所有的修改都會恢復到修改之前的狀態。在對修改的資料提交之前,對其他事務不可見。通俗的講就是儲存到資料庫永久儲存 感覺是滴 任何執行過程中的失敗,都將導致操作的失敗。髒讀 讀取到尚未提交的資料。...

資料庫避免髒讀,幻讀

一 髒讀 乙個事務讀取到了另外乙個事務沒有提交的資料 詳細解釋 髒讀就是指 當乙個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外乙個事務也訪問這個資料,然後使用了這個資料。因為這個資料是還沒有提交的資料,那麼另外乙個事務讀到的這個資料是髒資料,依據髒資料所做的操作...

資料庫的髒讀,幻讀,不可重複讀

參考 1.髒讀 指乙個事務a正在訪問資料,並且對該資料進行了修改,但是這種修改還沒有提交到資料庫中 也可能因為某些原因rollback了 這時候另外乙個事務b也訪問這個資料,然後使用了這個被a修改的資料,那麼這個資料就是髒的,並不是資料庫中真實的資料。這就被稱作髒讀。2.幻讀 指乙個事務a對乙個表中...