事务范围在打开连接对象时抛出异常,该平台不支持分布式事务。

24

TransactionScope在.net core 2.2中抛出异常

在这个例子中,我创建了一个TransactionScope作用域。 为一个数据库打开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()

3
除非你真正意图创建分布式事务,否则不要同时使用事务范围和Begin/CommitTransaction。使用TransactionScope是为了避免使用显式的Begin/Commit调用。 - Panagiotis Kanavos
TransactionScope 只能在 Windows 上运行。不确定您正在使用哪个操作系统。 - Ricardo Peres
我正在使用Windows 7和Visual Studio 2017 VS 15.9。我已经尝试删除SQL事务。 - Sushant
我们曾经在一个Transaction[Scope]中使用ExecuteReader执行了一个DELETE SQL语句。这将抛出PlatformNotSupportedException异常:"此平台不支持分布式事务"。 - Ashkan Nourzadeh
我也因为打开了多个连接而在单个数据库上遇到了这个错误。 - JasonCoder
2个回答

26

.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 事务中记录更改。


开放的 GitHub 问题为 https://github.com/dotnet/corefx/issues/13532。 - Tomas Karban
3
这个陈述:“第一个事务成功,第二个失败的可能性是存在的,但对于SQL Server来说,这是非常罕见的。” - 是不准确的。事务可能因为很多原因失败,这就是为什么分布式事务存在的原因!但如果你想要高吞吐量,那么分布式事务并不是一个好主意… - Mitch Wheat
这只是在那一点上发生的提交。两个事务都已经完成。因此,大多数潜在的事务失败已经发生了。更新的答案以澄清。 - David Browne - Microsoft
有任何更新吗? 我尝试了来自microsoft的解决方案,但不幸的是它没有起作用。我不确定这是否可能是由于2014 SQL Server引起的。或者是System.Data.SqlClient(因为Microsoft.Data.SqlClient无法在公司服务器上连接)。 - user13770736
1
该链接的GitHub问题已关闭;现在仅在Windows上实现了.NET 7。 - undefined
显示剩余2条评论

1

你认为 .NET 7 支持分布式事务吗? - Mohsen Saniee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接