2010-04-12 3 views
16

У нас есть веб-сервис на сервере №1 и база данных на сервере №2. Веб-служба использует область транзакций для создания распределенной транзакции. Все правильно.Исключение «Операция недействительна для состояния транзакции» с использованием TransactionScope

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

Полный StackTrace:

System.Transactions.TransactionState.EnlistPromotableSinglePhase (InternalTransaction ТХ, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, сделка AtomicTransaction) в System.Transactions.Transaction.EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification) в System.Data.SqlClient.SqlInternalConnection.EnlistNonNull (транзакция t в System.Data.SqlClient.SqlInte rnalConnection.Enlist (Transaction т в System.Data.SqlClient.SqlInternalConnectionTds.Activate (транзакция сделки) в System.Data.ProviderBase.DbConnectionInternal.ActivateConnection (Transaction сделки) в System.Data.ProviderBase.DbConnectionPool.GetConnection (DbConnection owningObject) в System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection owningConnection) в System.Data.ProviderBase.DbConnectionClosed.OpenConnection (DbConnection outerConnection, DbConnectionFactory ConnectionFactory) в System.Data.SqlClient.SqlConnection.Open() в NHibernate.Connection.DriverConnectionProvid er.GetConnection() в NHibernate.Impl.SessionFactoryImpl.OpenConnection()

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

+0

Какая ОС и как точно настроить MSDTC? –

+0

Какую форму конструктора TransactionScope() вы используете? – gprasant

+0

Hi Lanfear, Вы решили эту проблему? Мы получаем такую ​​же ошибку в тестовой среде. Тот же код в среде Dev отлично работает. –

ответ

30

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

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

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

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

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

+3

System.Transactions.Transaction.Current.TransactionInformation.Status помог мне точно определить, когда транзакция прерывалась. –

5

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

Я последовал шаги, описанные здесь, чтобы включить DTC и добавить исключение в брандмауэр Windows: Enable Network DTC Access for Windows Server 2008

Смежные вопросы