如果不對事務進行並發控制,我們看看資料庫並行作業是會有那些異常情形
1、丟失更新(Lost update)
兩個事務都同時更新一行資料,但是第二個事務卻中途失敗退出,導致對資料的兩個修改都失效了。
2、髒讀(Dirty Reads)
一個事務開始讀取了某行資料,但是另外一個事務已經更新了此資料但沒有能夠及時提交。這是相當危險的,因為很可能所有的操作都被復原。
3、非重複讀(Non-repeatable Reads)
一個事務對同一行資料重複讀取兩次,但是卻得到了不同的結果。同一查詢在同一事務中多次進行,由於其他提交事務所做的修改或刪除,每次返回不同的結果集,此時發生非重複讀。
4、二類丟失更新(Second lost updates problem)
無法重複讀取的特例。有兩個並發事務同時讀取同一行資料,然後其中一個對它進行修改提交,而另一個也進行了修改提交。這就會造成第一次寫操作失效。
5、幻像讀(Phantom Reads)
事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查
四個隔離等級:
ReadCommitted: 假設A事務對正在讀取資料Data放置了共用鎖定,那麼Data不能被其它事務改寫,所以當B事務對Data進行讀取時總和A讀取的Data資料是一致的,所以避免了髒讀。由於在A沒有提交之前可以對Data進行改寫,那麼B讀取到的某個值可能會在其讀取後被A更改從而導致了該值不能被重複取得;或者當B再次用相同的where字句時得到了和前一次不一樣資料的結果集,也就是幻像資料。
ReadUncommitted:
假設A事務即不發布共用鎖定,也不接受獨佔鎖,那麼並發的B或者其它事務可以改寫A事務讀取的資料,那麼並發的C事務讀取到的資料的狀態和A的或者B的資料都可能不一致,那麼。髒讀、不可重複讀取、幻象資料都可能存在。
RepeatableRead:
(注意MSDN原文中的第一句話:在查詢中使用的所有資料上放置鎖,所以不存在髒讀的情況)。
假設A事務對讀取的所有資料Data放置了鎖,以阻止其它事務對Data的更改,在A沒有提交之前,新的並發事務讀取到的資料如果存在於Data中,那麼該資料的狀態和A事務中的資料是一致的,從而避免了不可重複的讀取。但在A事務沒有結束之前,B事務可以插入新記錄到Data所在的表中,那麼其它事務再次用相同的where字句查詢時,得到的結果數可能上一次的不一致,也就是幻像資料。
Serializable:
在資料表上放置了獨佔鎖定,以防止在事務完成之前由其他使用者更新行或向資料集中插入行,這是最嚴格的鎖。它防止了髒讀、不可重複讀取和幻象資料。
以下是對照表:
| 隔離等級 |
髒讀(Dirty Read) |
不可重複讀取(NonRepeatable Read) |
幻讀(Phantom Read) |
| 讀未提交(Read uncommitted) |
可能 |
可能 |
可能 |
| 讀已提交(Read committed) |
不可能 |
可能 |
可能 |
| 可重複讀(Repeatable read) |
不可能 |
不可能 |
可能 |
| 可序列化(Serializable ) |
不可能 |
不可能 |
不可能 |