使用TRY-CATCH块在事务内返回

时间:2012-08-18 21:25:02

标签: sql sql-server sql-server-2008 tsql

我有以下代码,作为一个通用示例,我想知道如果事务在RETURN退出时保持打开状态。

BEGIN TRANSACTION
    BEGIN TRY
        IF NOT EXISTS(SELECT 1 FROM dbo.tblProducts WHERE intProductID = @intProductID)
            BEGIN
                SELECT 'Product does not exists' AS strMessage
                RETURN
            END

        UPDATE dbo.tblProducts SET
            curPrice = 10
        WHERE
            intProductID = @intProductID

        SELECT 'Success' AS strMessage

    END TRY 

    BEGIN CATCH
        SELECT ERROR_MESSAGE() AS strMessage
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION
    END CATCH

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION

4 个答案:

答案 0 :(得分:6)

应该像下面

BEGIN TRY
    SET NOCOUNT ON
    SET XACT_ABORT ON
    BEGIN TRANSACTION
        IF NOT EXISTS(SELECT 1 FROM dbo.tblProducts 
                          WHERE intProductID = @intProductID)
        BEGIN
            SELECT 'Product does not exists' AS strMessage
            Rollback TRan
            RETURN
        END

        UPDATE dbo.tblProducts SET
        curPrice = 10
        WHERE
        intProductID = @intProductID

        SELECT 'Success' AS strMessage
    COMMIT TRAN
END TRY 

BEGIN CATCH
    SELECT ERROR_MESSAGE() AS strMessage
    ROLLBACK TRANSACTION
END CATCH

答案 1 :(得分:3)

我只是通过运行上面的代码然后检查SELECT @@TRANCOUNT然后尝试ROLLBACK来尝试此操作。返回后,@@TRANCOUNT为1,我能够成功rollback表示transaction处于打开状态。

答案 2 :(得分:1)

此代码适用于嵌套事务:

BEGIN TRY
   IF @@TRANCOUNT > 0
      SAVE TRANSACTION MyTransactionName
   ELSE
       BEGIN TRANSACTION MyTransactionName

    IF NOT EXISTS(SELECT 1 FROM dbo.tblProducts WHERE intProductID = @intProductID)
        BEGIN
            SELECT 'Product does not exists' AS strMessage
            ROLLBACK TRANSACTION MyTransactionName
            RETURN
        END

    UPDATE dbo.tblProducts SET
        curPrice = 10
    WHERE
        intProductID = @intProductID

    SELECT 'Success' AS strMessage

    COMMIT TRANSACTION MyTransactionName
END TRY 

BEGIN CATCH
    SELECT ERROR_MESSAGE() AS strMessage
    ROLLBACK TRANSACTION MyTransactionName
END CATCH

答案 3 :(得分:0)

请参阅我在以下DBA.StackExchange答案中发布的存储过程模板,因为它解决了TRY / CATCH与事务的使用问题,并且它处理嵌套调用,即使在应用层中打开了事务:

Are we required to handle Transaction in C# Code as well as in Store procedure