Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transactionscope throwing exception this platform does not support distributed transactions while opening connection object

TransactionScope is throwing a exception in .net core 2.2

In this example I created a scope of TransactioScop. Opening SQL transaction for one database which is working fine.
After the first transaction I´m calling commit which will commit the SQL transaction. I try to open call transaction for another database while creating a transaction and the system is throwing an exception

This platform does not support distributed transactions.

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

Message

"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()
like image 748
Sushant Avatar asked May 27 '19 15:05

Sushant


1 Answers

.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.

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 commit 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;
            }

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.

like image 127
David Browne - Microsoft Avatar answered Oct 26 '22 07:10

David Browne - Microsoft