Исключение «Операция недопустима для состояния транзакции» с использованием TransactionScope - PullRequest
16 голосов
/ 12 апреля 2010

У нас есть веб-сервис на сервере № 1 и база данных на сервере № 2. Веб-сервис использует объем транзакции для создания распределенной транзакции. Все правильно.

И у нас есть еще одна база данных на сервере № 3. У нас были некоторые проблемы с этим сервером, и мы переустановили операционную систему и программное обеспечение. Мы настроили MSDTC и попытались использовать веб-сервис с сервера № 1 для связи с базой данных на этом сервере. И теперь после первого оператора select в области транзакции мы получаем: The operation is not valid for the state of the transaction. Это исключение попадает в каждый запрос веб-службы, если он использует область транзакции. Сервер № 2 и Сервер № 3 почти одинаковы. Разница может быть только в настройках. .NET Framework 3.5 с пакетом обновления 1 (SP1) и SQL Server SP3 на всех серверах.

Полная трассировка стека:

System.Transactions.TransactionState.EnlistPromotableSinglePhase (InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, транзакция atomicTransaction) в System.Transactions.Transaction.EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification) в System.Data.SqlClient.SqlInternalConnection.EnlistNonNull (Transaction t в System.Data.SqlClient.SqlInternalConnection.Enlist (транзакция t в System.Data.SqlClient.SqlInternalConnectionTds.Activate (Transaction транзакция) в System.Data.ProviderBase.DbConnectionInternal.ActivateConnection (Transaction транзакция) в System.Data.ProviderBase.DbConnectionPool.GetConnection (DbConnection владение объектом) в System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection владение соединением) в System.Data.ProviderBase.DbConnectionClosed.OpenConnection (DbConnection externalConnection, DbConnectionFactory connectionFactory) в System.Data.SqlClient.SqlConnection.Open () в NHibernate.Connection.DriverConnectionProvider.GetConnection () в NHibernate.Impl.SessionFactoryImpl.OpenConnection ()

Я искал это сообщение, но не нашел подходящего решения. Так какие настройки я должен проверить и что именно я должен сделать, чтобы это исправить?

Ответы [ 2 ]

30 голосов
/ 29 июня 2010

Lanfear, я столкнулся с тем же сообщением об ошибке и нашел решение. Ваша ситуация может быть другой, но я надеюсь, что следующие знания будут вам полезны.

System.Transactions.Transaction.Current.TransactionInformation.Status вернет статус текущей транзакции.

В каждом случае, когда выдается исключение с сообщением The operation is not valid for the state of the transaction, когда я перехожу через отладчик, я вижу, что состояние «Прервано» до того, как возникнет исключение.

В моем случае проблема была вызвана вложением двух транзакций друг в друга и ошибочным прерыванием обеих, когда я хотел прервать только одну. По-видимому, если вы используете TransactionScope конструктор по умолчанию New TransactionScope() с двумя вложенными транзакциями, отмена внутренней транзакции также отменяет внешнюю транзакцию. Решение состоит в том, чтобы использовать конструктор New TransactionScope(TransactionScopeOption.RequiresNew). Используя этот конструктор, внутренняя транзакция будет новой транзакцией, и ее прерывание не прервет внешнюю транзакцию.

Это решило мою проблему.

5 голосов
/ 08 апреля 2011

Включение координатора распределенных транзакций решило проблему для меня (это было сделано на обеих машинах: той, на которой есть веб-служба, и той, на которой есть база данных. Хотя не уверен, что она необходима для веб-службы).

Я выполнил действия, описанные здесь, чтобы включить DTC и добавить исключение для брандмауэра Windows: Включить сетевой доступ по DTC для Windows Server 2008

...