And*_*ock 4 c# transactions transactionscope
我有几个代码方法,如下所示:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我现在需要在外部事务中一起调用这些方法中的几个,所以我这样做了:
using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
method1();
method2();
method3();
}
Run Code Online (Sandbox Code Playgroud)
但它的做法是:
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()
Run Code Online (Sandbox Code Playgroud)
我是否需要更换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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以一起打电话给他们:
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
method1();
method2();
method3();
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
您调用的方法将共享同一个事务.