資料庫的事務在併發執行的時候,如果不考慮隔離性,就會產生以下幾種問題:
髒讀是指在乙個事務處理過程裡讀取了另乙個未提交的事務中的資料。
假設事務1正在訪問資料並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,事務2也訪問這個資料,然後使用了這個資料。因為這個資料是還沒有提交的資料,那麼事務2讀到的這個資料是儲存在資料庫記憶體中的資料,稱為髒讀。讀到的資料為臟資料,依據髒資料所做的操作可能是不正確的
不可重複讀是指在對於資料庫中的某個資料,乙個事務範圍內多次查詢卻返回了不同的資料值,這是由於在查詢間隔,被另乙個事務修改並提交了。
在事務1內,多次讀同乙個資料。在事務1還沒有結束時,事務2也訪問該同一資料並修改資料。那麼,在事務1的兩次讀資料之間。由於事務2的修改,那麼事務1兩次讀到的資料可能不一樣,這樣就發生了在乙個事務內兩次讀到的資料是不一樣的,因此稱為不可重複讀,即原始讀取不可重複。
相比起髒讀,不可重複讀讀取的是另乙個已經提交的事務,而髒讀讀取的是還未提交的事務。
在某些情況下,不可重複讀並不是問題,比如我們多次查詢某個資料當然以最後查詢得到的結果為主。但在另一些情況下就有可能發生問題,例如對於同乙個資料a和b依次查詢就可能不同,從而引發錯誤
幻讀是指當事務不是獨立執行時發生的一種現象。例如事務t1對乙個表中所有的行的某個資料項做了從「1」修改為「2」的操作,這時事務t2又對這個表中插入了一行資料項,而這個資料項的數值還是為「1」並且提交給資料庫。而操作事務t1的使用者如果再檢視剛剛修改的資料,會發現還有一行沒有修改,其實這行是從事務t2中新增的,就好像產生幻覺一樣,這就是發生了幻讀。
幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同乙個資料項,而幻讀針對的是一批資料整體(比如資料的個數)
為了避免以上問題,防止事務被其他事務干擾,因此多個併發的事務之間需要相互隔離。隔離等級分為4個級別,由低到高分別是為:
允許讀取未提交的資料。此時,可能會發生髒讀、不可重複讀、幻讀。這是併發最高,但也是一致性最差的隔離級別
只允許讀取已提交的資料。可以避免髒讀,但無法避免不可重複讀和幻讀
只允許讀取已提交的資料,並且在乙個事務兩次讀取乙個資料項期間,其他事務不得更新資料。可以避免髒讀和不可重複讀,無法避免幻讀。這也是mysql預設的隔離級別
保證所有的事務序列化排程。這種隔離級別可以避免髒讀、不可重複讀、幻讀
以**形式整理:
隔離級別
是否存在髒讀
是否存在不可重複讀
是否存在幻讀
讀未提交是是
是讀已提交否是
是可重複讀否否
是序列化否否
否
資料庫併發問題和隔離級別
為什麼會出現 髒讀 因為沒有 select 操作沒有規矩。為什麼會出現 不可重複讀 因為 update 操作沒有規矩。為什麼會出現 幻讀 因為 insert 和 delete 操作沒有規矩。讀未提 read uncommitted 能預防啥?啥都預防不了。讀提交 read committed 能預防...
資料庫事務 併發問題及隔離級別
四 事務的隔離級別 我們學習資料庫,經常看到資料庫事務,acid事務等相關的概念,拋開資料庫,可以將事務更廣泛的定義為 乙個或多個原子操作組合而成的執行單元。更通俗的講,就是將幾件小事或是幾個步驟 起來作為乙個整體來處理對待。而資料庫事務,即一條或多條不可再分的資料操作指令組合而成的執行單元。乙個標...
資料庫的併發問題以及資料庫的隔離級別
什麼是資料庫的併發問題 在同一時刻,多個事務進行同一資料記錄進行操作,導致的問題。資料庫併發產生的五個問題 1 髒讀 乙個事務讀到另一事務未提交的更新資料。在a事務內,由於b事務對a記錄進行了修改但未提交,而a事務馬上讀取了這個提交的值,在這個值的基礎上進了一系列的操作,但另乙個事務突然出回滾,導致...