我有几种看起来像这样的代码方法:
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()
我需要用
IDbTransactions
替换TransactionScopes
吗?我应该为外部内部范围使用什么
TransactionScopeOption
?我猜我想要外部的RequiresNew
和内部的Required
吗?这些方法仍将单独调用(即,没有外部
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# - 如何将IDbTransactions包装在TransactionScope中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6277335/