Tsql 在T-SQL的catch块中回滚一个事务之前,我必须对事务进行计数吗?

Tsql 在T-SQL的catch块中回滚一个事务之前,我必须对事务进行计数吗?,tsql,sql-server-2008,stored-procedures,error-handling,transactions,Tsql,Sql Server 2008,Stored Procedures,Error Handling,Transactions,在每个SQL Server 2008存储过程的末尾都有下一个块 BEGIN TRY BEGIN TRAN -- my code COMMIT END TRY BEGIN CATCH IF (@@trancount > 0) BEGIN ROLLBACK DECLARE @message NVARCHAR(MAX) DECLARE @state INT SELECT @messag

在每个SQL Server 2008存储过程的末尾都有下一个块

BEGIN TRY
    BEGIN TRAN
        -- my code
    COMMIT
END TRY
BEGIN CATCH
    IF (@@trancount > 0)
    BEGIN
        ROLLBACK
        DECLARE @message NVARCHAR(MAX)
        DECLARE @state INT
        SELECT @message = ERROR_MESSAGE(), @state = ERROR_STATE()
        RAISERROR (@message, 11, @state)
    END
END CATCH
是否可以将
CATCH
-块切换到

BEGIN CATCH
    ROLLBACK
    DECLARE @message NVARCHAR(MAX)
    DECLARE @state INT
    SELECT @message = ERROR_MESSAGE(), @state = ERROR_STATE()
    RAISERROR (@message, 11, @state)
END CATCH
或者只是

BEGIN CATCH
    ROLLBACK
END CATCH

在尝试回滚之前,您需要检查作用域中是否存在事务

您可以使用以下选项:

BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;
这将回滚事务,但不会向应用程序报告任何错误


查看更多信息。

事实上,如果我已经开始了新的交易,我就不会开始新的交易

这涉及嵌套存储过程、分布式TXN和TransactionScope

记住,无论如何都有


如果我总是在事务范围内呢?查看我编辑的帖子如果你知道你在一个事务中,那么你唯一需要的语句就是
ROLLBACK
语句。您的应用程序仍然不会收到任何错误报告。我的意思是,我总是在每个DML存储过程的开头启动事务(并尝试阻止)。所以我的问题是-我必须在相应的catch块中检查@trancount吗?@abatishchev:是的:它可能已经滚动了bck(例如在触发器中)
DECLARE @StartTranCount int

BEGIN TRY
    SET @StartTranCount = @@TRANCOUNT
    IF @StartTranCount = 0 BEGIN TRAN
        -- my code
    IF @StartTranCount = 0 COMMIT TRAN
END TRY
BEGIN CATCH
    IF @StartTranCount = 0 AND @@trancount > 0
    BEGIN
        ROLLBACK TRAN
        DECLARE @message NVARCHAR(MAX)
        DECLARE @state INT
        SELECT @message = ERROR_MESSAGE(), @state = ERROR_STATE()
        RAISERROR (@message, 11, @state)
    END
    /*
    or just
    IF @StartTranCount = 0 AND @@trancount  
        ROLLBACK TRAN
    */
END CATCH