リモート MSMQ をトランザクションで使用するにはどうすればよいですか?
-
02-07-2019 - |
質問
私は、MSMQ からメッセージを取得し、レガシー システム (Baan) にポストする Windows サービスを作成しています。投稿が失敗したり、投稿中にマシンがダウンしたりしても、メッセージを失いたくないのです。したがって、MSMQ トランザクションを使用しています。失敗したら中止し、成功したらコミットします。
ローカル キューに対して作業する場合、このコードはうまく機能します。しかし、実稼働環境では、サービスを実行しているマシン (または複数のマシン) をキュー自体から分離する必要があります。リモート キューに対してテストすると、System.Messaging.MessageQueueException がスローされます。「トランザクションの使用法が無効です。」
問題のキューがトランザクションであることを確認しました。
キューから受け取るコードは次のとおりです。
// Begin a transaction.
_currentTransaction = new MessageQueueTransaction();
_currentTransaction.Begin();
Message message = queue.Receive(wait ? _queueTimeout : TimeSpan.Zero, _currentTransaction);
_logger.Info("Received a message on queue {0}: {1}.", queue.Path, message.Label);
WORK_ITEM item = (WORK_ITEM)message.Body;
return item;
答え
それ以来、私はに切り替えました SQLサービスブローカー. 。これはリモート トランザクション受信をサポートしていますが、MSMQ 3.0 はサポートしていません。さらに、クラスタ化してバックアップした SQL Server インスタンスがすでに使用されています。
解決
これが問題の原因だと思うので、使用している MSMQ のバージョンについて質問するコメントを残しました。トランザクション受信は、MSMQ の以前のバージョンでは実装されていませんでした。そういう場合は、これ ブログ投稿 オプションを説明します。
他のヒント
MSDTC が両方のマシンで実行されている場合、TransactionScope の使用は機能します。
MessageQueue queue = new MessageQueue("myqueue");
using (TransactionScope tx = new TransactionScope()) {
Message message = queue.Receive(MessageQueueTransactionType.Automatic);
tx.Complete();
}
それ以来、私はに切り替えました SQLサービスブローカー. 。これはリモート トランザクション受信をサポートしていますが、MSMQ 3.0 はサポートしていません。さらに、クラスタ化してバックアップした SQL Server インスタンスがすでに使用されています。
トランザクション スコープを使用するには、MSDTC がインストールされ、リモート クライアント接続がアクティブ化されていることを事前に確認する必要があります。
MSDTC のインストールは問題ありませんが、リモート クライアント接続を有効にするとサーバーが再起動する必要があります (Windows Server 2003 の場合はこれに当てはまります)。
この投稿が役立つかもしれません:MSDTC とリモート クライアント接続をアクティブ化する方法
リモート MSMQ は使用しないでください (リモート MSMQ トランザクションをサポートするには、MSMQ 4.0 にアップグレードしてください)。1)あるいは、1つのWebサービスを作成してメッセージをプッシュすることができますトランザクションスコープとして