You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring.NET从2.0.2升级到3.0.2后出现TransactionException问题求助

问题描述

将Spring.NET包从2.0.2版本升级到3.0.2版本后,[Transaction]属性拦截器的行为发生变化,出现如下异常:

System.Transactions.TransactionException
  HResult=0x80131501
  Message=The operation is not valid for the state of the transaction.
  Source=System.Transactions
  StackTrace:
   at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction, Guid promoterType)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
   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.ProviderBase.DbConnectionInternal.ActivateConnection(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.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()

Inner Exception 1:
TransactionPromotionException: Failure while attempting to promote transaction.

Inner Exception 2:
SqlException: Distributed transactions (DTC) are not supported with transactions that access memory optimized tables or natively compiled modules.

除版本升级外无其他变更,需解释异常原因并提供解决办法。

异常原因分析

  • Spring.NET 3.0.2版本对[Transaction]拦截器的默认事务处理逻辑做了调整,默认启用了事务自动提升机制——当事务内出现跨连接操作时,会自动将本地事务升级为分布式事务(DTC)。
  • 业务逻辑中涉及了SQL Server的内存优化表或原生编译模块,而SQL Server明确禁止这类对象参与分布式事务,因此当事务被尝试提升为DTC时,底层SQL客户端抛出了不支持的异常。

解决办法

  • 显式配置事务属性,禁用自动提升:在[Transaction]属性中指定合适的事务传播行为与隔离级别,确保事务保持为本地事务。例如:
    [Transaction(TransactionPropagation.Required, IsolationLevel = IsolationLevel.Snapshot)]
    
    Snapshot隔离级别是内存优化表支持的隔离级别之一,同时可避免触发事务提升。
  • 确保单事务内复用数据库连接:检查代码中是否存在同一事务内多次打开新数据库连接的情况,统一复用已有的连接,避免触发Spring.NET的事务提升逻辑。
  • 调整内存优化表的事务策略:内存优化表仅支持本地事务,且要求使用SNAPSHOT或READ COMMITTED SNAPSHOT隔离级别,确保事务配置符合此要求。
  • 修改Spring.NET配置还原旧行为:如果暂时无法调整业务代码,可以在Spring.NET的配置文件中修改事务拦截器的设置,关闭自动事务提升,还原到2.0.2版本的事务处理逻辑。

内容的提问来源于stack exchange,提问作者user1193850

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:45:05