【问题标题】:Transaction in Stored Proc + Client Code存储过程 + 客户端代码中的事务
【发布时间】:2011-09-29 02:12:31
【问题描述】:

我有一个 SQL Server 存储过程,它可以创建这样的 TRANSACTION:

BEGIN TRY
    BEGIN TRANSACTION

    INSERT INTO Table1 ...
    INSERT INTO Table2 ...

    COMMIT
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK
END CATCH

此存储过程将插入到两个单独的表中。如果其中一个失败,它将回滚。

我还有以下创建事务范围的 .net 代码:

using( var scope = new TransactionScope() )
{
    SqlCommand cmd1 = connection.CreateCommand(); 
    SqlCommand cmd2 = connection.CreateCommand();

    // ...

    cmd1.ExecuteNonQuery();
    cmd2.ExecuteNonQuery();

    scope.Complete();
}

如果我的存储过程和我的代码都在创建事务会发生什么?这会导致问题/需要成为分布式事务还是只要我只创建一个到数据库的连接就可以了吗?

【问题讨论】:

    标签: c# .net sql-server transactionscope


    【解决方案1】:

    除非你有充分的理由,否则我只会在一个地方或另一个地方进行交易。

    如果可能的话,我希望那个地方是数据库。这减少了往返,更易于测试,将其与系统的其他组件隔离,减少暴露的数据库表面积,并通过强制操作通过定义明确的接口来保护数据库周边的完整性。

    【讨论】:

      【解决方案2】:

      在这种情况下,如果您的某个存储过程失败,它将使用内部事务回滚。您的代码会认为它已经完成并提交分布式事务。这是您想要的吗,因为分布式事务是毫无意义的,因为每个事务都将单独运行。

      如果您希望两者都运行或都不运行,请从存储过程中删除您的事务并仅使用分布式事务。

      【讨论】:

      • 存储过程会将错误冒泡,而不是吞下它。抱歉,我的示例没有显示这一点。
      • @Dismissile - 您捕获错误并回滚事务。在您的CATCH 中没有抛出错误
      • 我的意思是我的例子没有显示我的 RAISERROR,即使我的真实场景是这样做的。
      猜你喜欢
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 2011-12-25
      • 2016-04-22
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 2013-09-02
      相关资源
      最近更新 更多