隔離級別
隔離級別
隔離級別:一個事務必須與由其他事務進行的資源或數據更改相隔離的程度。隔離級別從允許的併發副作用(例如,臟讀或虛擬讀取)的角度進行描述。
事務指定一個隔離級別,該隔離級別定義一個事務必須與由其他事務進行的資源或數據更改相隔離的程度。隔離級別從允許的併發副作用(例如,臟讀或幻讀)的角度進行描述。
讀取數據時是否佔用鎖以及所請求的鎖類型。
佔用讀取鎖的時間。
引用其他事務修改的行的讀取操作是否:
在該行上的排他鎖被釋放之前阻塞其他事務。
檢索在啟動語句或事務時存在的行的已提交版本。
讀取未提交的數據修改。
選擇事務隔離級別不影響為保護數據修改而獲取的鎖。事務總是在其修改的任何數據上獲取排他鎖並在事務完成之前持有該鎖,不管為該事務設置了什麼樣的隔離級別。對於讀取操作,事務隔離級別主要定義保護級別,以防受到其他事務所做更改的影響。
較低的隔離級別可以增強許多用戶同時訪問數據的能力,但也增加了用戶可能遇到的併發副作用(例如臟讀或丟失更新)的數量。相反,較高的隔離級別減少了用戶可能遇到的併發副作用的類型,但需要更多的系統資源,並增加了一個事務阻塞其他事務的可能性。應平衡應用程序的數據完整性要求與每個隔離級別的開銷,在此基礎上選擇相應的隔離級別。最高隔離級別(可序列化)保證事務在每次重複讀取操作時都能準確檢索到相同的數據,但需要通過執行某種級別的鎖定來完成此操作,而鎖定可能會影響多用戶系統中的其他用戶。最低隔離級別(未提交讀)可以檢索其他事務已經修改、但未提交的數據。在未提交讀中,所有併發副作用都可能發生,但因為沒有讀取鎖定或版本控制,所以開銷最少。
控制隔離數據以供一個進程使用並防止其它進程干擾的程度的事務屬性。設置隔離級別定義了 SQL Server 會話中所有 SELECT 語句的默認鎖定行為。
當多個事務 同時進行時,通過設置隔離級別來處理臟讀、不可重複讀、幻讀事件
read uncommitted | 0 未提交讀
將查詢的隔離級別指定為 0。
可以讀臟數據
讀臟數據:一事務對數據進行了增刪改,但未提交,有可能回滾,另一事務卻讀取了未提交的數據
read committed | 1 已提交讀
將查詢的隔離級別指定為 1。
避免臟讀,但可以出現不可重複讀和幻讀
不可重複讀:一事務對數據進行了更新或刪除操作,另一事務兩次查詢的數據不一致
幻像讀:一事務對數據進行了新增操作,另一事務兩次查詢的數據不一致
repeatable read | 2 可重複讀
將查詢的事務隔離級別指定為 2。
避免臟讀,不可重複讀,允許幻像讀
serializable | 3 可序列化
將查詢的隔離級別指定為 3。
串列化讀,事務只能一個一個執行,避免了臟讀、不可重複讀、幻讀
執行效率慢(我遇到過一種情況,用時是隔離級別1的30倍),使用時慎重
SNAPSHOT
當讀取數據時,可以保證讀操作讀取的行是事務開始時可用的最後提交版本。
這意味著這種隔離級別可以保證讀取的是已經提交過的數據,並且可以實現可重複讀,
也能確保不會幻讀。不過這種隔離級別使用的不是共享鎖,而是行版本控制。
SQL Server 2005以後的版本支持。
下表顯示了不同隔離級別允許的併發副作用。
隔離級別 | 臟讀 | 不可重複讀 | 虛擬讀取 |
未提交讀 | 是 | 是 | 是 |
已提交讀 | 否 | 是 | 是 |
可重複讀 | 否 | 否 | 是 |
快照 | 否 | 否 | 否 |
可序列化 | 否 | 否 | 否 |