使用TransactionScope的异常“操作对事务状态无效”

时间:2010-04-12 15:29:43

标签: c# sql-server nhibernate msdtc

我们在服务器#1上有一个Web服务,在服务器#2上有一个数据库。 Web服务使用事务范围来生成分布式事务。一切都是正确的。

我们在服务器#3上有另一个数据库。我们在服务器上遇到了一些问题,我们重新安装了操作系统和软件。我们配置了MSDTC并尝试使用来自服务器#1的Web服务与该服务器上的数据库进行通信。 现在,在事务范围内的第一个select语句之后,我们得到:The operation is not valid for the state of the transaction。如果使用事务范围,则此异常属于每个Web服务请求。 服务器#2和服务器#3几乎相似。差异只能在设置中。 在所有服务器上安装.NET Framework 3.5 SP1和SQL Server SP3。

完整的堆栈跟踪:

  

System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction   tx,IPromotableSinglePhaseNotification   promotableSinglePhaseNotification,Transaction atomicTransaction)   System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification   promotableSinglePhaseNotification)в   System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(交易   tвSystem.Data.SqlClient.SqlInternalConnection.Enlist(Transactiontв   System.Data.SqlClient.SqlInternalConnectionTds.Activate(交易   交易)   System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(交易   交易)   System.Data.ProviderBase.DbConnectionPool.GetConnection(的DbConnection   拥有对象)   System.Data.ProviderBase.DbConnectionFactory.GetConnection(的DbConnection   拥有连接)   System.Data.ProviderBase.DbConnectionClosed.OpenConnection(的DbConnection   outerConnection,DbConnectionFactory connectionFactory)   System.Data.SqlClient.SqlConnection.Open()в   NHibernate.Connection.DriverConnectionProvider.GetConnection()в   NHibernate.Impl.SessionFactoryImpl.OpenConnection()

我搜索了这条消息,但没有找到任何合适的解决方案。 那么我应该检查哪些设置以及我应该做些什么来解决它?

2 个答案:

答案 0 :(得分:30)

Lanfear,我遇到了同样的错误消息,我找到了解决方案。您的情况可能有所不同,但我希望以下知识对您有用。

System.Transactions.Transaction.Current.TransactionInformation.Status将返回当前交易的状态。

在使用消息The operation is not valid for the state of the transaction抛出异常的每种情况下,当我逐步使用调试器时,我会看到在抛出异常之前状态为“Aborted”。

在我的情况下,问题是由于在我想要仅中止一个事务时将两个事务嵌套在彼此内并错误地中止两个事件。显然,如果将TransactionScope默认构造函数New TransactionScope()与两个嵌套事务一起使用,则中止内部事务也会中止外部事务。解决方案是使用构造函数New TransactionScope(TransactionScopeOption.RequiresNew)使用此构造函数,内部事务将是一个新事务,并且中止它不会中止外部事务。

这解决了我的问题。

答案 1 :(得分:5)

启用分布式事务协调器为我解决了这个问题(这是在两台机器上完成的:具有Web服务的那台机器和具有数据库的机器。不确定Web服务是否需要它。)< / p>

我按照此处描述的步骤启用DTC并向Windows防火墙添加例外:Enable Network DTC Access for Windows Server 2008