c# - 如何将 IDbTransactions 包装在 TransactionScope 中

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

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

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 以及一起调用,所以我仍然需要它们在事务上是安全的。

谢谢

最佳答案

我相信您在这里混合了技术,应该避免将 TransactionScopeDbTransaction 一起使用,因为 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/

相关文章:

c# - 什么时候使用缓存太多了?

c# - 为什么在 c# .net Windows 应用程序中添加 dll 引用时出错?

c# - 实现轻量级 TransactionScope

c# - 在 C# 中使用文件的 TransactionScope

c# - 如果在 Using block 末尾未调用 TransactionScope.Complete,Transaction 会发生什么

c# - CSLA .NET - Child_Fetch 未按预期工作

C# ProcessWindowStyle.Minimized 不适用于 PSR.exe

transactions - 是否可以从原始交易中找到的 'scriptSig' 中解码公钥?

java - weblogic部署InternalException : Transaction marked rollback or not expected transaction

sql-server-2008 - SQL Server 与 ADO.NET 的默认事务隔离级别是什么?