Sql-Server

事務隔離級別聲明的位置差異 - 在事務內部/外部?

  • July 16, 2019

今天,當我看到以下結構時,我一直在查看我們系統上的一些儲存過程:

(虛擬碼表示實際SP,伺服器使用預設隔離級別):

CREATE PROCEDURE ...
AS
BEGIN
 IF NOT EXISTS(SELECT ...) 
 BEGIN
   RETURN; 
 END

 BEGIN TRAN
   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

   DML...
   DML...
   DML...
 COMMIT
END

我還沒有看到在事務邊界內聲明事務隔離級別,我想知道它的效果是什麼?

送出事務後是否恢復隔離級別(因此,如果送出後有其他語句 - 它們的隔離級別是什麼)?

在這種情況下,我認為如果在事務開始之前聲明隔離級別不會有任何區別。是這樣嗎?

大多數情況下,我看到這一點有點吃驚,因為我只見過在事務之外聲明事務隔離,而不是在事務內部,我想知道 - 為什麼?這樣做有什麼好處。

以下是SET TRANSACTION ISOLATION LEVEL 文件的相關摘錄。

一次只能設置一個隔離級別選項,並且它會一直為該連接設置,直到它被顯式更改。事務中執行的所有讀取操作都在指定隔離級別的規則下執行,除非語句的 FROM 子句中的表提示為表指定不同的鎖定或版本控制行為。

它接著說:

如果在儲存過程或觸發器中發出 SET TRANSACTION ISOLATION LEVEL,則當對象返回控制權時,隔離級別將重置為呼叫對象時有效的級別。例如,如果在批處理中設置 REPEATABLE READ,然後批處理呼叫將隔離級別設置為 SERIALIZABLE 的儲存過程,則當儲存過程將控制權返回給批處理時,隔離級別設置將恢復為 REPEATABLE READ。

注意這裡沒有提到BEGIN TRANSACTION,COMMIT等。這些事務控制語句不影響目前會話事務隔離級別。

我看不出與在BEGIN TRAN. 也許開發人員想確保該級別對讀者來說是顯而易見的,並認為最好的位置是在事務邊界,而不是必須查看 proc 程式碼的開頭。

引用自:https://dba.stackexchange.com/questions/242971