我有几个看起来像这样的代码方法:
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/