6

在什么情况下可以将代码包裹在System.Transactions.TransactionScope静止提交中,即使抛出异常并且最外层范围从未调用过提交?

有一个包含在 中的顶级方法using (var tx = new TransactionScope()),它调用的方法也TransactionScope以相同的方式使用。

我正在使用带有关联表适配器的类型化数据集。可能是适配器中的命令由于某种原因没有登记吗?你们有谁知道如何检查他们是否在环境 TransactionScope 中登记?

4

4 回答 4

9

答案原来是因为我是在对象TransactionScope之后创建SqlConnection对象。

我从这个搬家:

using (new ConnectionScope())
using (var transaction = new TransactionScope())
{
    // Do something that modifies data

    transaction.Complete();
}

对此:

using (var transaction = new TransactionScope())
using (new ConnectionScope())
{
    // Do something that modifies data

    transaction.Complete();
}

现在它可以工作了!

所以这个故事的寓意是创造你的TransactionScope 第一个

于 2009-11-10T16:16:32.117 回答
2

明显的场景是明确指定新的 ( RequiresNew) / null ( Suppress) 事务 - 但也有可能导致连接错过事务的超时/解除绑定故障。请参阅此较早的帖子(修复只是连接字符串更改)或完整详细信息

于 2009-11-10T12:37:24.407 回答
0

请注意如何TransactionScope工作:
它在使用范围开始时设置属性System.Transactions.Transaction.Current,然后在使用范围结束时将其设置回以前的值。

先前的值取决于给定范围的声明位置。它可以在另一个范围内。


您可以像这样修改代码:

using (var sqlConnection = new ConnectionScope())
using (var transaction = new TransactionScope())
{
    sqlConnection.EnlistTransaction(System.Transactions.Transaction.Current);
    // Do something that modifies data
    transaction.Complete();
}

我向那些代码更复杂并且不能简单地更改代码以首先打开数据库连接的人展示了这种可能性。

于 2014-05-23T09:31:49.287 回答
0

这个例子(C#,.NetFramework 4.7.1)展示了我们如何可以持久化到数据库,即使代码被包装在一个TransactionScope. 第一个insert将被回滚,第二个insert将在没有事务的情况下插入。

请参阅我的相关帖子,我在其中寻求有关如何检测此问题的帮助。


using (var transactionScope = new TransactionScope())
{
    using (var connection = new SqlConnection("Server=localhost;Database=TestDB;Trusted_Connection=True"))
    {
        connection.Open();

        new SqlCommand($"INSERT INTO TestTable VALUES('This will be rolled back later')", connection).ExecuteNonQuery();

        var someNestedTransaction = connection.BeginTransaction();
        someNestedTransaction.Rollback();

        new SqlCommand($"INSERT INTO TestTable VALUES('This is not in a transaction, and will be committed')", connection).ExecuteNonQuery();
    }

    throw new Exception("Exiting.");

    transactionScope.Complete();
}

于 2019-09-05T08:45:00.523 回答