首页 > 解决方案 > 为什么失败的事务不使用 TransactionScope 回滚?

问题描述

我想要实现的是:我从 2 个不同的数据库调用存储过程。SP 在表中有一个简单的插入条目。如果两个事务都成功,则没有问题,但是当我尝试在第二个 DB SP 中引发异常时,第一个不会回滚。我在这里做错了什么?

C#代码:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
    // Update DB1
    using (SqlConnection con = new SqlConnection(connectionString1))
    {
        con.Open();
        SqlCommand command1 = new SqlCommand("sp_1", con);
        command1.ExecuteNonQuery();

        // Update DB2 
        using (SqlConnection con2 = new SqlConnection(connectionString2))
        {
            con2.Open();
            SqlCommand command2 = new SqlCommand("sp_2", con2);
            command2.ExecuteNonQuery();
        }
    }
    scope.Complete();
}

DB1 SP:

BEGIN
    INSERT INTO TABLE_X1 VALUES(...)
END

DB2 SP:

BEGIN
    THROW 51000, 'The record does not exist.', 1; 

    INSERT INTO TABLE_X2 VALUES(...)
END

标签: c#sqlrollbacktransactionscopesqltransaction

解决方案


您需要使用TransactionScopeOption.Required选项来启用交易。

如果两个数据库在同一个 SQL 服务器上,则使用相同的连接以避免触发分布式事务(如果连接字符串完全相同,则不应发生这种情况)。

TransactionScope:避免分布式事务

如果您要使用事务并且如果数据库位于不同的服务器上(或同一服务器上的不同实例),那么就无法避免分布式事务。在这种情况下,启用 MSDTC,请参阅此处的详细信息

https://www.dbrnd.com/2016/11/sql-server-how-to-configure-and-enable-msdtc-microsoft-distributed-transaction-coordinator/


推荐阅读