首页 > 解决方案 > Transactionscope 抛出异常此平台在打开连接对象时不支持分布式事务

问题描述

TransactionScope 在 .net core 2.2 中抛出异常

在这个例子中,我创建了一个scope of TransactioScop. 为一个运行良好的数据库打开 SQL 事务。
在我调用的第一个事务之后commit,它将提交 SQL 事务。我尝试call transaction在创建事务时打开另一个数据库,但系统抛出异常

该平台不支持分布式事务。

试图删除 SQL 事务

C#

using (TransactionScope scop =new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
{       
    _db1UOW.Begin(); //creating sql transaction
    await _db1UOW.IDenialDetailsRepositorydb1.InsertDenialDetails(denialsDetails);
    await _db1UOW.IRuleDetailsRepositorydb1.InsertRulesDetails(rulesDetails);
    _db1UOW.Commit(); //commitng sql transaction

    _db2UOW.Begin(); //creating sql transaction (but while opening connection object its throwing exception as This platform does not support distributed transactions)
    await _db2UOW.IRuleDetailsRepository.GetRulesDetails();
    await _db2UOW.IDenialDetailsRepository.InsertDenialDetails(denialsDetails);
    var data = await _db2UOW.IRuleDetailsRepository.InsertRulesDetails(rulesDetails);
    _db2UOW.Commit(); //commitng sql transaction
    scop.Complete();
}

信息

"This platform does not support distributed transactions."  at System.Transactions.Distributed.DistributedTransactionManager.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
   at System.Transactions.TransactionInterop.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
   at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
   at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
   at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
   at System.Transactions.Transaction.Promote()
   at System.Transactions.TransactionInterop.ConvertToDistributedTransaction(Transaction transaction)
   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
   at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
   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.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()

标签: c#sql-server.net-core

解决方案


.NET Core 不支持分布式事务,因为它需要在每个平台上使用不同的事务管理器。它可能会在未来出现(是正在进行的问题),但目前任何需要两个不同资源管理器的事务都会抛出此异常。

相反,您可以协调单独的事务。让两个单独的事务完成它们的工作,然后同时提交它们。有可能第一次提交成功而第二次提交失败,但对于 SQL Server,这将是非常罕见的情况。就像是:

            _db1UOW.Begin(); //creating sql transaction
            await _db1UOW.IDenialDetailsRepositorydb1.InsertDenialDetails(denialsDetails);
            await _db1UOW.IRuleDetailsRepositorydb1.InsertRulesDetails(rulesDetails);

            _db2UOW.Begin(); //creating sql transaction 
            await _db2UOW.IRuleDetailsRepository.GetRulesDetails();
            await _db2UOW.IDenialDetailsRepository.InsertDenialDetails(denialsDetails);
            var data = await _db2UOW.IRuleDetailsRepository.InsertRulesDetails(rulesDetails);

            _db1UOW.Commit(); //commitng sql transaction
            try
            {
               _db2UOW.Commit(); //commitng sql transaction
            }
            catch (Exception ex)
            {
               LogError("Second transaction failed to commit after first one committed.  Administrators may need to fix stuff");
               throw;
            }

或者,如果两个数据库位于同一台服务器上,您可以使用带有单个 SqlConnection 的跨数据库查询来获取单个 SQL Server 事务中的更改。


推荐阅读