想象一下,我有以下存盤程序:
CREATE PROCEDURE [dbo].[CheckIfDataIsOk]
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
-- bunch of checks that read row 1
COMMIT TRANSACTION
編輯:我放入READ UNCOMMITTED了存盤程序,但它也可以READ COMMITTED。關鍵是第一個存盤程序回傳的結果純粹是基于讀取表中的資料。
然后我想使用它:
CREATE PROCEDURE [dbo].[DoSomethingImportant]
AS
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
EXECUTE [dbo].[CheckIfDataIsOk]
-- if "data is ok", then do some work that modifies row1
COMMIT TRANSACTION
當“可重復讀”隔離級別通過第一個存盤程序呼叫間接從 row1 讀取資料時,它是否會放置一個讀鎖?或者它只會在它觸及存盤程序本身中的 row1 時才放鎖?
uj5u.com熱心網友回復:
- 不要使用 READ UNCOMMITED/NOLOCK。在存在并發事務的情況下,您可以并且將會得到不正確的結果。在這里你
如果“資料正常”,則做一些修改 row1 的作業
使用 READ UNCOMMITTED 很簡單,而且顯然是錯誤的。在讀取您打算修改的行時,您應該使用限制性鎖,而不僅僅是共享鎖(或 NOLOCK)。讀取要修改的事務中的行時,應該使用 UPDLOCK 提示進行讀取。
- 檔案中清楚地解釋了該行為:
除了一個例外,您可以在事務期間隨時從一種隔離級別切換到另一種隔離級別。從任何隔離級別更改為 SNAPSHOT 隔離時會發生例外。這樣做會導致事務失敗并回滾。但是,您可以將在 SNAPSHOT 隔離中啟動的事務更改為任何其他隔離級別。
當您將事務從一個隔離級別更改為另一個隔離級別時,更改后讀取的資源將根據新級別的規則受到保護。更改前讀取的資源繼續根據上一級的規則受到保護。例如,如果事務從 READ COMMITTED 更改為 SERIALIZABLE,則更改后獲取的共享鎖現在會一直保留到事務結束。
如果在存盤程序或觸發器中發出 SET TRANSACTION ISOLATION LEVEL,當物件回傳控制時,隔離級別將重置為呼叫物件時的有效級別。例如,如果在批處理中設定 REPEATABLE READ,然后該批處理呼叫將隔離級別設定為 SERIALIZABLE 的存盤程序,則當存盤程序將控制權回傳給批處理時,隔離級別設定將恢復為 REPEATABLE READ。
設定事務隔離級別
uj5u.com熱心網友回復:
從另一個存盤程序執行一個存盤程序時,執行背景關系會發生變化。當控制回傳時,對執行背景關系(例如SET選項或隔離級別)的任何更改都會回滾到它們之前的狀態。
所以當你執行
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
隔離級別已更改。
但是,在執行時
EXECUTE [dbo].[CheckIfDataIsOk]
背景關系被保存,以便之后可以回滾。
CREATE PROCEDURE [dbo].[CheckIfDataIsOk]
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
-- bunches of checks that read row 1
COMMIT TRANSACTION
此處隔離級別在整個程序中發生了變化(請注意,內部事務在外部事務提交之前實際上不會提交)。所以被訪問的行沒有被鎖定。
-- if "data is ok", then do some work that modifies row1
COMMIT TRANSACTION
此時,原始設定被放回原處。但是,先前讀取的行尚未鎖定,并且可能會更改。
請注意,REPEATABLE READ這不會阻止讀取新行,它只會阻止更改先前讀取的行。所以它實際上可能不是一般意義上的“可重復”。
老實說,我會將隔離級別從更改為READ UNCOMMITTED更好的。它可能導致完全錯誤的結果,例如多次讀取頁面、讀取根據約束根本不應該實作的資料等。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/374175.html
標籤:sql sql-server 查询语句
上一篇:T-SQL資料透視表不使用IN和基于MIN()和MAX的資料透視資料中另一列的值
下一篇:如何有效地更新依賴于先前記錄的表
