Transactionscope 抛出异常此平台在打开连接对象时不支持分布式事务

Transactionscope 抛出异常此平台在打开连接对象时不支持分布式事务

问题描述:

TransactionScope 抛出异常我使用的是 .net core 2.2

TransactionScope throwing exception I am using .net core 2.2

在这个例子中,我首先创建 TransactioScop 的范围,然后为一个工作正常的数据库打开 SQL 事务,然后在第一个事务之后我调用将提交 SQL 事务的 commit 然后我尝试在创建时打开另一个数据库的调用事务事务系统抛出异常

In this example I am first creating scope of TransactioScop then opening SQL transaction for one database which is working fine then after the first transaction I am calling commit which will commit SQL transaction then I trying to open call transaction for another database while creating transaction system throwing an exception

作为消息此平台不支持分布式事务."

as Message "This platform does not support distributed transactions."

试图删除 SQL 事务

tried to remove SQL transaction

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()

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

.NET Core doesn't support Distributed Transactions because it would require a different transaction manager on each platform. It may appear in the future (here's the issue in-progress), but for now any Transaction that would require two different resource managers will throw this exception.

相反,您可以协调单独的交易.让两个单独的事务完成它们的工作,然后同时提交它们.有一种可能性,第一个成功而第二个失败,但对于 SQL Server,这种情况非常罕见.类似的东西:

Instead you can coordinate separate transactions. Have two separate transactions complete their work, and then commit them both. There is a possibility that the first one succeeds and the second one fails, but for SQL Server, that would be a very rare occurance. Something like:

            _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 事务中的更改.

Or if the two databases are on the same server you can use cross-database queries with a single SqlConnection to enlist the changes in a single SQL Server transaction.