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

在 SQL Server 中永遠會啟用資料列版本控制架構,並且有多個功能會使用此架構。除了提供資料列版本控制式的隔離等級之外,它也用來支援觸發程序中所做的修改以及 Multiple Active Result Set (MARS) 工作階段中所做的修改,還支援 ONLINE 索引作業的資料讀取。

資料列版本控制式的隔離等級是在資料庫層級啟用。從已啟用之資料庫存取物件的應用程式,可以使用下列隔離等級執行查詢:

  • 透過將 READ_COMMITTED_SNAPSHOT 資料庫選項設為 ON,進而使用資料列版本控制的讀取認可,如下列程式碼範例所示:

    ALTER DATABASE AdventureWorks2008R2
        SET READ_COMMITTED_SNAPSHOT ON;
    

    針對 READ_COMMITTED_SNAPSHOT 啟用資料庫時,在讀取認可隔離等級下執行的所有查詢都會使用資料列版本控制,這表示讀取作業不會封鎖更新作業。

  • 將 ALLOW_SNAPSHOT_ISOLATION 資料庫選項設定為 ON 來隔離快照集,如下列程式碼範例所示:

    ALTER DATABASE AdventureWorks2008R2
        SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    在快照隔離下執行的交易可以存取在資料庫中已針對快照啟用的資料表。若要存取尚未針對快照啟用的資料表,您必須變更隔離等級。例如,下列程式碼範例會顯示 SELECT 陳述式,該陳述式會在執行快照集交易的同時聯結兩個資料表。其中一個資料表屬於未啟用快照隔離的資料庫。當 SELECT 陳述式在快照隔離下執行時,將無法順利執行。

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

    下列程式碼範例所示的是經過修改的同一個 SELECT 陳述式,可將交易隔離等級變更為讀取認可。由於此項變更,就可以順利執行 SELECT 陳述式。

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            WITH (READCOMMITTED)
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

如需如何在應用程式內設定隔離等級的詳細資訊,請參閱<調整交易隔離等級>。

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

使用資料列版本控制式的隔離等級時,請考慮下列限制:

  • 無法在 tempdb、msdb 或 master 中啟用 READ_COMMITTED_SNAPSHOT。

  • 全域暫存資料表會儲存在 tempdb 中。存取快照集交易內的全域暫存資料表時,必須符合下列其中一項:

    • 在 tempdb 中,將 ALLOW_SNAPSHOT_ISOLATION 資料庫選項設為 ON。

    • 使用隔離提示來變更陳述式的隔離等級。

  • 發生下列情形時,快照集交易會失敗:

    • 啟動快照集交易之後,且於快照集交易存取資料庫之前,資料庫都是唯讀的。

    • 如果從多重資料庫存取物件,在快照集交易啟動之後,但在快照集交易存取資料庫之前,會以發生資料庫復原的方式變更資料庫狀態。例如:資料庫設為 OFFLINE 然後設為 ONLINE、自動關閉及開啟資料庫,或者卸離和附加資料庫。

  • 快照隔離中不支援分散式交易,包括在分散式資料分割資料庫中的查詢。

  • SQL Server 不會保留多個版本的系統中繼資料。資料表上的資料定義語言 (DDL) 陳述式和其他資料庫物件 (索引、檢視、資料類型、預存程序和 Common Language Runtime 函數) 會變更中繼資料。如果 DDL 陳述式修改了物件,則對快照隔離下的物件進行任何並行參考都會導致快照集交易失敗。當 READ_COMMITTED_SNAPSHOT 資料庫選項為 ON 時,讀取認可交易就沒有這項限制。

    例如,資料庫管理員會執行下列 ALTER INDEX 陳述式。

    USE AdventureWorks2008R2;
    GO
    ALTER INDEX AK_Employee_LoginID
        ON HumanResources.Employee REBUILD;
    GO
    

    執行 ALTER INDEX 陳述式時,任何使用中的快照集交易都會出現錯誤 (如果快照集交易嘗試在執行 ALTER INDEX 陳述式之後參考 HumanResources.Employee 資料表)。使用資料列版本控制的讀取認可交易將不受影響。

    [!附註]

    BULK INSERT 作業可能會造成變更目標資料表中繼資料 (例如,停用條件約束檢查時)。如果發生這種狀況,存取大量插入資料表的並行快照隔離交易會失敗。