SQL Server 快照隔離

SQL Server 的早期版本支持 SQL-92 標準中定義的四個隔離級別:
READ UNCOMMITTED 是限制性最弱的隔離級別,因為該級別忽略其他事務放置的鎖。 使用 READ UNCOMMITTED 級別執行的事務,可以讀取尚未由其他事務提交的修改后的數據值;這些行為稱為“臟”讀。
READ COMMITTED 是 SQL Server 默認的隔離級別。 該級別通過指定語句不能讀取其他事務已修改但是尚未提交的數據值,禁止執行臟讀。 在當前事務中的各個語句執行之間,其他事務仍可以修改、插入或刪除數據,從而產生無法重復的讀操作,或“影子”數據。
REPEATABLE READ 是比 READ COMMITTED 限制性更強的隔離級別。 該級別包括 READ COMMITTED,并且另外指定了在當前事務提交之前,其他任何事務均不可以修改或刪除當前事務已讀取的數據。 并發性低于 READ COMMITTED,因為已讀數據的共享鎖在整個事務期間持有,而不是在每個語句結束時釋放。
SERIALIZABLE 是限制性最強的隔離級別,因為該級別鎖定整個范圍的鍵,并一直持有鎖,直到事務完成。 該級別包括 REPEATABLE READ,并增加了在事務完成之前,其他事務不能向事務已讀取的范圍插入新行的限制。


鋪墊了這么多,終于介紹到了今天的主角,"快照”一詞反映的情況是:事務中的所有查詢根據事務開始那一刻數據庫的狀態,看到數據庫的相同版本(即快照)。 不會在快照事務中的基礎數據行或數據頁上獲取鎖,這樣可以執行其他事務,而不會被以前未完成的事務所阻止。 修改數據的事務不會阻止讀取數據的事務,讀取數據的事務不會阻止寫入數據的事務,就好像通常情況下在 SQL Server 中使用默認的 READ COMMITTED 隔離級別一樣。 這種無阻止的行為也大大降低了復雜事務出現死鎖的可能性。
SQL Server 通過引入 SNAPSHOT 隔離級別并另外實現 READ COMMITTED 而引入了對 SQL-92 隔離級別的擴展。READ_COMMITTED_SNAPSHOT 隔離級別可以透明地替換所有事務的 READ COMMITTED。

  • SNAPSHOT 隔離指定在一個事務中讀取的數據永遠不會反映其他同時進行的事務所作的更改。
  • 事務使用事務開始時存在的數據行版本。
  • 在讀取數據時不會對數據放置任何鎖,所以,SNAPSHOT 事務不會阻止其他事務寫入數據。
  • 寫入數據的事務不會阻止快照事務讀取數據。
    啟用快照隔離之后,每個事務的已更新行版本在 tempdb 中維護。 唯一的事務序列號標識每個事務,并且為每個行版本記錄這些唯一的編號。 事務使用序列號在事務序列號之前的最新行版本。 事務將忽略在事務開始之后創建的更新的行版本。

快照隔離和行版本化的工作原理

啟用 SNAPSHOT 隔離級別時,每次更新行時,SQL Server 數據庫引擎在 tempdb 中存儲原始行的副本,并為該行添加事務序列號。
以下是發生的事件序列:

  • 新的事務啟動,并為該事務分配一個事務序列號。
  • 數據庫引擎在事務中讀取某行,并從 tempdb 中檢索其序列號與事務序列號最接近并且小于事務序列號的行版本。
  • 數據庫引擎檢查事務編號是否不在未提交事務的事務編號列表中,這些未提交事務是在快照事務開始時進入活動狀態的。
  • 事務從 tempdb 中讀取自事務開始以來最新的行版本。
    事務不會看到事務開始后插入的新行,因為這些序列號值將大于事務序列號的值。
  • 當前事務將看到事務開始后刪除的行,因為 tempdb 中的行版本具有更低的序列號值。
    快照隔離的實際效果是事務看到在事務開始時存在的所有數據,不會在基礎表上授予或放置任何鎖。 在存在爭用的情況下,這樣可以改進性能。
    快照事務始終使用開放式并發控制,不賦予可能阻止其他事務更新行的任何鎖。 如果快照事務嘗試提交對事務開始后已更改的行的更新,事務將回滾并引發錯誤。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容