【问题标题】:Transactions and Rollbacks in SQLSQL 中的事务和回滚
【发布时间】:2014-09-29 19:37:28
【问题描述】:

我正在寻找有关针对数据库的交易的一些说明。

我有一个从 .NET 应用程序调用的存储过程。存储过程被包装在一个带有开始事务和提交/回滚的 Try-Catch 中。在 try-catch 内部最多有四个可能的其他存储过程被调用,它们对表进行更新/插入。我相信这些存储过程也包含在带有开始事务和提交/回滚的 try-catch 中。

如果这四个 sproc 中的任何一个在插入/更新时发现错误,我想回滚所有内容,但由于所有 sproc 都单独包装在它们自己的 try-catch 中,并带有 begin tran 和 commit/rollback tran 基本上不会一次一个 sproc 完成了它提交的调用,但如果第二个失败,第一个不会回滚。 这是它的工作方式吗? 被调用的主存储过程如下所示:

BEGIN TRY
BEGIN TRANSACTION


    EXEC dbo.test_call1 @AccountName

    EXEC dbo.test_call2 @accountNbr,@person

    EXEC dbo.test_call3 @person,@order

    EXEC dbo.test_call4 @order,@quantity



COMMIT TRANSACTION  
END TRY

BEGIN CATCH
    ROLLBACK TRANSACTION
END CATCH

test_call1 与此类似:

BEGIN TRY
BEGIN TRANSACTION


    BEGIN
      INSERT INTO dbo.Account
       (AccountName,AccountNumber,Source)
       VALUES
       (@AccountName,123456,'online' )


        END
 COMMIT TRANSACTION 
 END TRY

BEGIN CATCH
 ROLLBACK TRANSACTION
END CATCH

END

【问题讨论】:

    标签: sql transactions try-catch


    【解决方案1】:

    (假设这是 SQL Server)

    内部事务本质上被忽略,外部事务的动作是整个事务的结果。 From MSDN:

    SQL Server 数据库引擎忽略提交内部事务。基于在最外层事务结束时采取的操作,事务要么被提交,要么被回滚。如果提交了外部事务,则也提交了内部嵌套事务。如果外部事务被回滚,那么所有内部事务也会被回滚,而不管内部事务是否被单独提交。

    【讨论】:

    • 因此,如果 sproc 在任何地方遇到错误,dbo.test_call1、dbo.test_call2、dbo.test_call3、dbo.test_call4 中的任何开始事务提交/回滚都将被忽略。因此,例如它在 dbo.test_call3 中遇到错误将在 test-call1 和 dbo.test_call2 中插入/更新并回滚?
    • 如果任何内部事务回滚,则其余事务可能完成并提交。该过程将以错误结束(最后一次提交将出错,因为回滚将@@trancount 重置为 0 并且尝试提交将出错)但回滚之后的任何内容仍然可以提交。每次通话后,您可以尝试检查 @@TRANCOUNT 是否为 0,如果是则回滚所有内容。
    • 将主存储过程包装在事务中并从内部调用中删除事务是否有意义,这样如果它在任何地方出错,它将回滚所有内容而不之前提交任何内容?
    • @BS123 是的,这是一个更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多