web-dev-qa-db-ja.com

TransactionScopeを使用した例外「操作はトランザクションの状態に対して無効です」

サーバー#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 ServerSP3がすべてのサーバーにインストールされています。

完全なスタックトレース:

System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx、IPromotableSinglePhaseNotification promotableSinglePhaseNotification、Transaction atomicTransaction)System System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotSificationPromotiontableSinglePhaseNotification promotableSinglePhaseNotification)×System .Enlist(Transactiont×System.Data.SqlClient.SqlInternalConnectionTds.Activate(トランザクショントランザクション)×System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(トランザクショントランザクション)×System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnectionowningObject)×システム。 Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)×System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection、DbConnectionFactory connectionFactory)×System.Data.SqlClient.SqlConnection.Open()×NHiberna te.Connection.DriverConnectionProvider.GetConnection()×NHibernate.Impl.SessionFactoryImpl.OpenConnection()

このメッセージを検索しましたが、適切な解決策は見つかりませんでした。では、どの設定を確認する必要があり、それを修正するには正確に何をする必要がありますか?

18

Lanfear、私は同じエラーメッセージに出くわし、解決策を見つけました。状況は異なるかもしれませんが、以下の知識がお役に立てば幸いです。

_System.Transactions.Transaction.Current.TransactionInformation.Status_は、現在のトランザクションのステータスを返します。

メッセージ_The operation is not valid for the state of the transaction_で例外がスローされる場合はいずれも、デバッガーをステップスルーすると、例外がスローされる前にステータスが「中止」になっていることがわかります。

私の場合、この問題は、2つのトランザクションを相互にネストし、1つだけを中止したいのに、誤って両方を中止したことが原因でした。どうやら、ネストされた2つのトランザクションでTransactionScopeデフォルトコンストラクタNew TransactionScope()を使用すると、内部トランザクションを中止すると、外部トランザクションも中止されます。解決策は、コンストラクターNew TransactionScope(TransactionScopeOption.RequiresNew)を使用することです。このコンストラクターを使用すると、内部トランザクションは新しいトランザクションになり、中止しても外部トランザクションは中止されません。

これで私の問題は解決しました。

30

分散トランザクションコーディネーターを有効にすると、問題が解決しました(これは、Webサービスを備えたマシンとデータベースを備えたマシンの両方で行われました。Webサービスに必要かどうかはわかりません)。

ここで説明する手順に従って、DTCを有効にし、Windowsファイアウォールに例外を追加しました。 Windows Server 2008のネットワークDTCアクセスを有効にする

5
SzilardD