星期四, 9月 30, 2021

[SQL] Nonrepeatable Read

SQL Server 預設隔離層級為 Read Committed,該隔離層級不會有 Dirty Read 問題,但會發生 Nonrepeatable Read,也就是交易內多次讀取資料,結果會有所不同

指定陳述式不能讀取其他交易已修改而尚未認可的資料。 這個選項可避免中途讀取。 目前交易內個別陳述式之間的其他交易可以變更資料,這會產生不可重複的讀取或虛設項目資料。 這個選項是 SQL Server 的預設值。
Sample Code
USE AdventureWorks
GO 

DROP TABLE IF EXISTS tbRepeatableReadDemo

CREATE TABLE tbRepeatableReadDemo
(
  ID int identity(1,1) Primary key,
  Col1 int
)

INSERT INTO tbRepeatableReadDemo (Col1) 
VALUES(1) , (2) , (3) , (4) , (5)

-- 顯示建立資料
SELECT * FROM tbRepeatableReadDemo

----- Nonrepteated Read Demo
----- Session1
-- Step1:開啟交易並讀取資料,此時交易還在
BEGIN TRAN
SELECT * FROM tbRepeatableReadDemo
WAITFOR DELAY '00:00:05'
-- Step3:再次讀取資料 
SELECT * FROM tbRepeatableReadDemo

----- Session2
-- Step2:更新資料,把數字都加 1
UPDATE tbRepeatableReadDemo
SET Col1 = Col1 + 1
上述 Code 流程圖示化

  [SQL] Nonrepteated Read-1
Session1 查詢結果

[SQL] Nonrepteated Read-2 

因為交易層級層級 - Read Committed,對於 S-Lock 是查詢完畢後立即釋放,而非交易完成後釋放,所以 Session2 的 Update 可以順利取得 X-Lock 來進行資料更新

沒有留言:

張貼留言