資料列版本控管 SnapShot Isolation V.S Read Committed Snapshot ( 二 )

資料列版本控管 SnapShot Isolation VS Read Committed Snapshot(二)

 

在資料列版本控管 SnapShot Isolation VS Read Committed Snapshot()中我們有談到

 

SQL2005版後提供『資料列版本控管(Row Version)有兩種。

 

1. 「快照集隔離(Snapshot Isolation)

 

2. 「讀取認可快照(Read Committed Snapshot)

 

SnapShot Isolation VS Read Committed Snapshot()中我們已經先介紹過快照集隔離

 

(Snapshot Isolation),而本篇就來針對讀取認可快照(Read Committed Snapshot)簡介一下

 

 

 

 

步驟一我們先將資料庫的ALLOW_SNAPSHOT_ISOLATION設為OFF並開啟

 

READ_COMMITTED_SNAPSHOT,執行完語法後我們檢視一下SYS.DATABASES

 

看看資料庫設定值是否正確(如下圖所示)

clip_image002

 

 

 

步驟二開啟另一個ID52Session,我們利用DBCC USEROPTIONS指令來檢視這一

 

Session的設定值。其中要看的部分就是如下圖紅色圈選處Isolation Level,我們可以知

 

道這一個Session的預設Isolation Level就是Read Committed Snapshot

clip_image004

 

 

 

步驟三我們先Select 出目前EmployeeID=1FirstName,該欄位資料為ROCK。然後開啟

 

交易並將該筆資料的FirstName改為CAREY(如下圖紅色圈選處),且不Commit此交易。

clip_image006

 

 

 

步驟四我們開啟一個新的Session,其ID53。我們利用此Session

 

Select EmployeeID=1的資料,看看是否會因為步驟三Update的交易沒

 

Commit而導致Blocking情形。測試結果如下圖,我們並沒有被Blocking

 

且可以順利取得資料,欄位資料為ROCK而不是CAREY,因為異動為

 

CAREY的交易尚未被Commit

clip_image008

 

 

 

 

步驟五我們將步驟三Update交易Commit掉,讓FirstName欄位資料正式變更為CAREY

clip_image010

 

 

 

步驟六我們回到Session 53,這一次我們開啟交易然後同樣Select EmployeeID=1的資料

 

。如下圖所示回傳內容是CAREY了,同樣的我們先不要Commit這一個交易。

clip_image012

 

 

 

 

步驟七我們回到Session 52,並將資料由CAREY異動為DANIEL,並且Commit交易。

 

此時EmployeeID=1FirstName欄位內容已被變更為DANIEL(如下圖所示)

clip_image014

 

 

 

步驟八我們回到步驟六尚未Commit交易的Session 53並且加入一個DML命令,

 

UPDATE Employees SET FirstName=’ROCK’WHERE EmployeeID=1來異動該筆資料

 

看看是否會跟SNAPSHOT ISOLATION一樣因為資料內容已被另一個Session異動過

 

而發生錯誤呢 ? 由下圖結果看來我們也成功地將資料內容改為ROCK並不會像

 

SNAPSHOT ISOLATION一樣產生錯誤

clip_image016

小結 :

 

不論是「快照集隔離(Snapshot Isolation)」,或「讀取認可快照(Read Committed Snapshot)」,

 

都能避免掉 SQL Server 預設的交易隔離等級 Read Committed。可大幅降低BlockingDeadlock

 

的發生,但這樣的做法會大量使用到TempDB,因此TempDB的優化會是另一個重要的課題。

 

而兩種做法對於資料列版本控管方式並不相同,因此請依據自身商業邏輯來選擇適當的方法。

 

讀取認可快照(Read Committed Snapshot)基本不必修改程式碼即可套用,而快照集隔離

 

(Snapshot Isolation)則須注意Update的問題。

 

20200929補充:Snapshot Isolation採用讀寫都採用樂觀鎖定,而Read Committed Snapshot在讀的時候採樂觀,但寫入採悲觀鎖定。因此Read Committed Snapshot它在每個語句的統計信息中獲取所有提交數據的快照版本信息。所以其他Session即便在交易中,一旦源頭Commit了,其他Session就能取得最新的資料內容(交易中)。因此不會像Snapshot Isolation那樣在其他Session更新已更新過資料會發生錯誤的情況產生。

 

 

參考資料來源

 

使用資料列版本控制式的隔離等級

 

讀書隨手筆記 - SQL Server 效能調校

我是ROCK

rockchang@mails.fju.edu.tw