【问题标题】:SQL Server transactions errors due to different Isolation Levels由于不同的隔离级别导致的 SQL Server 事务错误
【发布时间】:2018-01-15 22:47:23
【问题描述】:

我创建了以下存储过程来检查事务中的隔离级别行为:

CREATE PROCEDURE ReadCommittedIsolationLevel
AS
BEGIN
    BEGIN TRANSACTION t1
    BEGIN TRY
        EXEC SnapShotIsolationLevel
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        PRINT ERROR_MESSAGE()
        ROLLBACK TRANSACTION t1
    END CATCH
END

CREATE PROCEDURE SnapShotIsolationLevel
AS
BEGIN
    SET TRANSACTION ISOLATION LEVEL SNAPSHOT        
    BEGIN TRANSACTION t2
        BEGIN TRY
            SELECT TOP 20 * 
            FROM Orders 
            ORDER BY 1 DESC

            COMMIT
        END TRY
        BEGIN CATCH
            PRINT ERROR_MESSAGE()
            ROLLBACK TRAN t2
        END CATCH
END

然后我运行这个:

EXEC ReadCommittedIsolationLevel

我收到此错误:

数据库“MyDataBase”中的事务失败,因为该语句在快照隔离下运行,但事务未在快照隔离下启动。事务启动后,您不能将事务的隔离级别更改为快照,除非该事务最初是在快照隔离级别下启动的。
无法回滚 t2。未找到该名称的事务或保存点。

如果我删除事务并像普通存储过程一样运行它,它就可以正常工作。

这是为什么呢?

【问题讨论】:

    标签: sql-server transactions


    【解决方案1】:

    错误给了你正确的解释:

    您不能将事务的隔离级别更改为快照 交易开始后。

    SQL Server 没有nested transactions,唯一真正的事务是在Read Committed 下启动的外部事务,下一个begin tran 除了递增@@trancount 之外什么都不做。你可以在这里阅读更多内容:A SQL Server DBA myth a day: (26/30) nested transactions are real by Paul Randal

    Snapshot Isolation 表示transaction level 的数据一致,而不是语句级别(RCSI),因此您应该在事务开始时将Isolation level 更改为Snapshot,否则您无法将其更改为Snapshot完全没有。

    【讨论】:

    • 当它没有包含在事务中时,您可以在需要时将 TIL 更改为快照,因为根本没有打开的事务,所以在“事务已开始并且有人试图将 TIL 更改为快照"
    • 这里唯一明显的是你不想理解事务级别一致性是什么意思。 Read Committed 允许不可重复的读取,因此假设您在 Read Committed 打开 tran,从选项卡计数(),得到 1000 行,然后将 TIL 更改为快照并再次从选项卡计数()。假设它是允许的。但是在您的第一次和第二次计数之间,标签中添加了 100 行新行。现在你的事务中有不可重复的读取,你的读取是 1000 和 1100,没有事务级别的一致性。
    • (Continue) 事务级一致性是指在一个事务中可以多次从同一张表中读取,数据会是相同的。因此,如果您首先设置 TIL SNAPSHOT 然后开始您的 tran,您的第一次读取给您 1000 行,而您的第二次读取给您 1000 行,因为您将在 BEGIN TRAN 的那一刻收到数据,并且 BEGIN TRAN 的那个精确时刻被记住仅当您在 SNAPSHOT TIL 中操作时。在您更改为 SNAPSHOT 之前,当您的事务开始时,没有记住开始 tran 时刻
    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多