SQL Server 的早期版本支持 SQL-92 標(biāo)準(zhǔn)中定義的四個隔離級別:
READ UNCOMMITTED
是限制性最弱的隔離級別袭异,因為該級別忽略其他事務(wù)放置的鎖烟号。 使用 READ UNCOMMITTED 級別執(zhí)行的事務(wù)商膊,可以讀取尚未由其他事務(wù)提交的修改后的數(shù)據(jù)值售睹;這些行為稱為“臟”讀尊残。
READ COMMITTED
是 SQL Server 默認(rèn)的隔離級別绍些。 該級別通過指定語句不能讀取其他事務(wù)已修改但是尚未提交的數(shù)據(jù)值捞慌,禁止執(zhí)行臟讀。 在當(dāng)前事務(wù)中的各個語句執(zhí)行之間柬批,其他事務(wù)仍可以修改啸澡、插入或刪除數(shù)據(jù),從而產(chǎn)生無法重復(fù)的讀操作氮帐,或“影子”數(shù)據(jù)嗅虏。
REPEATABLE READ
是比 READ COMMITTED 限制性更強(qiáng)的隔離級別。 該級別包括 READ COMMITTED上沐,并且另外指定了在當(dāng)前事務(wù)提交之前皮服,其他任何事務(wù)均不可以修改或刪除當(dāng)前事務(wù)已讀取的數(shù)據(jù)。 并發(fā)性低于 READ COMMITTED,因為已讀數(shù)據(jù)的共享鎖在整個事務(wù)期間持有龄广,而不是在每個語句結(jié)束時釋放硫眯。
SERIALIZABLE
是限制性最強(qiáng)的隔離級別,因為該級別鎖定整個范圍的鍵择同,并一直持有鎖两入,直到事務(wù)完成。 該級別包括 REPEATABLE READ敲才,并增加了在事務(wù)完成之前裹纳,其他事務(wù)不能向事務(wù)已讀取的范圍插入新行的限制。
鋪墊了這么多紧武,終于介紹到了今天的主角痊夭,"快照”一詞反映的情況是:事務(wù)中的所有查詢根據(jù)事務(wù)開始那一刻數(shù)據(jù)庫的狀態(tài),看到數(shù)據(jù)庫的相同版本(即快照)脏里。 不會在快照事務(wù)中的基礎(chǔ)數(shù)據(jù)行或數(shù)據(jù)頁上獲取鎖她我,這樣可以執(zhí)行其他事務(wù),而不會被以前未完成的事務(wù)所阻止迫横。 修改數(shù)據(jù)的事務(wù)不會阻止讀取數(shù)據(jù)的事務(wù)番舆,讀取數(shù)據(jù)的事務(wù)不會阻止寫入數(shù)據(jù)的事務(wù),就好像通常情況下在 SQL Server 中使用默認(rèn)的 READ COMMITTED 隔離級別一樣矾踱。 這種無阻止的行為也大大降低了復(fù)雜事務(wù)出現(xiàn)死鎖的可能性恨狈。
SQL Server 通過引入 SNAPSHOT
隔離級別并另外實現(xiàn) READ COMMITTED 而引入了對 SQL-92 隔離級別的擴(kuò)展。READ_COMMITTED_SNAPSHOT 隔離級別可以透明地替換所有事務(wù)的 READ COMMITTED呛讲。
- SNAPSHOT 隔離指定在一個事務(wù)中讀取的數(shù)據(jù)永遠(yuǎn)不會反映其他同時進(jìn)行的事務(wù)所作的更改禾怠。
- 事務(wù)使用事務(wù)開始時存在的數(shù)據(jù)行版本。
- 在讀取數(shù)據(jù)時不會對數(shù)據(jù)放置任何鎖贝搁,所以吗氏,SNAPSHOT 事務(wù)不會阻止其他事務(wù)寫入數(shù)據(jù)。
- 寫入數(shù)據(jù)的事務(wù)不會阻止快照事務(wù)讀取數(shù)據(jù)雷逆。
啟用快照隔離之后弦讽,每個事務(wù)的已更新行版本在 tempdb 中維護(hù)。 唯一的事務(wù)序列號標(biāo)識每個事務(wù)膀哲,并且為每個行版本記錄這些唯一的編號往产。 事務(wù)使用序列號在事務(wù)序列號之前的最新行版本。 事務(wù)將忽略在事務(wù)開始之后創(chuàng)建的更新的行版本某宪。
快照隔離和行版本化的工作原理
啟用 SNAPSHOT 隔離級別時仿村,每次更新行時,SQL Server 數(shù)據(jù)庫引擎在 tempdb 中存儲原始行的副本兴喂,并為該行添加事務(wù)序列號蔼囊。
以下是發(fā)生的事件序列:
- 新的事務(wù)啟動包颁,并為該事務(wù)分配一個事務(wù)序列號。
- 數(shù)據(jù)庫引擎在事務(wù)中讀取某行压真,并從 tempdb 中檢索其序列號與事務(wù)序列號最接近并且小于事務(wù)序列號的行版本娩嚼。
- 數(shù)據(jù)庫引擎檢查事務(wù)編號是否不在未提交事務(wù)的事務(wù)編號列表中,這些未提交事務(wù)是在快照事務(wù)開始時進(jìn)入活動狀態(tài)的滴肿。
- 事務(wù)從 tempdb 中讀取自事務(wù)開始以來最新的行版本岳悟。
事務(wù)不會看到事務(wù)開始后插入的新行,因為這些序列號值將大于事務(wù)序列號的值泼差。 - 當(dāng)前事務(wù)將看到事務(wù)開始后刪除的行贵少,因為 tempdb 中的行版本具有更低的序列號值。
快照隔離的實際效果是事務(wù)看到在事務(wù)開始時存在的所有數(shù)據(jù)堆缘,不會在基礎(chǔ)表上授予或放置任何鎖滔灶。 在存在爭用的情況下,這樣可以改進(jìn)性能吼肥。
快照事務(wù)始終使用開放式并發(fā)控制录平,不賦予可能阻止其他事務(wù)更新行的任何鎖。 如果快照事務(wù)嘗試提交對事務(wù)開始后已更改的行的更新缀皱,事務(wù)將回滾并引發(fā)錯誤斗这。