如何包装IDbTransactions在一个TransactionScope [英] How to wrap IDbTransactions in a TransactionScope

查看:185
本文介绍了如何包装IDbTransactions在一个TransactionScope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个代码的方法是这样的:

I have several code methods that look like this:

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();
        }
    }
}



我现在需要调用几个这些方法的共同外部事务里面,所以我这样做:

I now need to call several of these methods together inside an outer transaction, So I did this:

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



但这样做的:

but its doing:

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()

我是否需要更换 IDbTransactions TransactionScopes

什么 TransactionScopeOption 我应该使用外部的内部范围?即时猜测我想 RequiresNew 的外部和要求的胆?

What TransactionScopeOption should I use for the outer an inner scopes? Im guessing i want RequiresNew for the outer and Required for the inners?

方法仍然会逐个调用(即没有外部的的TransactionScope 以及在一起,所以我还需要他们事务安全。

The methods will still be called individually (i.e. without an outer TransactionScope as well as together, so I still need them to be transactionally safe.

感谢

推荐答案

我相信你在这里混的技术,并应避免使用的TransactionScope DbTransaction ,因为一起的TransactionScope 创建一个隐含的事务。

I believe you are mixing technologies here and should avoid using TransactionScope and DbTransaction together because TransactionScope creates an implicit transaction.

因此,我建议有类似的方法:

So I would recommend to have your methods similar to:

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();
    }
}



然后你可以叫他们起来:

Then you can call them together:

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

    scope.Complete();
}

和你打电话将共享相同的事务的方法。

and the methods you called will share the same transaction.

这篇关于如何包装IDbTransactions在一个TransactionScope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆