编程语言
首页 > 编程语言> > c# – 如何在TransactionScope中包装IDbTransactions

c# – 如何在TransactionScope中包装IDbTransactions

作者:互联网

我有几个代码方法,如下所示:

using (var connection = this.connectionFactory.GetConnection())
{
    connection.Open();
    using (var transaction = connection.BeginTransaction())
    {
        using (var command = connection.CreateCommand())
        {
            command.Transaction = transaction;
            command.CommandText = "foo";
            command.ExecuteNonQuery();
            transaction.Commit();
        }
    }
}

我现在需要在外部事务中一起调用这些方法中的几个,所以我这样做了:

using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    method1();
    method2();
    method3();
}

但它的做法是:

The operation is not valid for the state of the transaction.
   at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()

我需要用TransactionScopes替换IDbTransactions吗?

我应该将什么TransactionScopeOption用于外部范围?我猜我想要外部的RequiresNew和内部的必需品?

这些方法仍将被单独调用(即没有外部TransactionScope以及一起调用,所以我仍然需要它们在事务上是安全的.

谢谢

解决方法:

我相信你在这里混合技术,应该避免一起使用TransactionScope和DbTransaction,因为TransactionScope创建了一个隐式事务.

所以我建议让你的方法类似于:

using (var connection = this.connectionFactory.GetConnection())
{
    connection.Open();
    using (TransactionScope scope = new TransactionScope())
    {
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "foo";
            command.ExecuteNonQuery();
        }
        scope.Complete();
    }
}

然后你可以一起打电话给他们:

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    method1();
    method2();
    method3();

    scope.Complete();
}

您调用的方法将共享同一个事务.

标签:c,transactions,transactionscope
来源: https://codeday.me/bug/20190530/1187106.html