3

MSSQLデータベースとIBMMQキューの両方を含む必要がある.NETTransactionScopeがあります。

.NET 4.0(VS2010)、SQL 2008R2、MQ Server 6.0、MQClient7.0.1.9をフルマネージドモードで使用しています。すべてのコンポーネントは異なるマシンで実行されています。

私が見つけたものから、次のパターンが機能するはずです: http://publib.boulder.ibm.com/infocenter/wmqv7/v7r1/index.jsp? topic=%2Fcom.ibm.mq.doc%2Fun11400_.htm

暗黙的トランザクション次のコードは、WebSphereMQ.NETアプリケーションが.NET暗黙的トランザクションプログラミングを使用してメッセージを送信する方法を説明しています。

Using(TransactionScope scope = new TransactionScope()){Q.Put(putMsg、pmo); scope.Complete(); }

Q.close(); qMgr.Disconect();}

私のコードでは、これは次のようになります。

  // mq properties
  properties = new Hashtable();
  properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
  properties.Add(MQC.HOST_NAME_PROPERTY, HOSTNAME);
  properties.Add(MQC.PORT_PROPERTY, PORTNUMBER);
  properties.Add(MQC.CHANNEL_PROPERTY, CHANNELNAME);

  _queueManager = new MQQueueManager(queueManagerName, properties);
  _queue = _queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
  _gmo = new MQGetMessageOptions();
  _gmo.Options |= MQC.MQGMO_WAIT;
  _gmo.Options |= MQC.MQGMO_SYNCPOINT;
  _gmo.WaitInterval = 1000;  // 1 seconds wait

  // in a loop
  using (TransactionScope t = new TransactionScope())
  {

  var message = new MQMessage();
  try
  {
     _queue.Get(message, _gmo);
  }
  catch (MQException mqe)
  { 
     message = null;
     if (mqe.ReasonCode == 2033)
     {
          Console.WriteLine("No message available");
     }
     else
     {
          throw;
      }
   }
   t.Complete();
 }

//Afterwards:

  if (_queue != null)
   {
  _queue.Close();
  _queue = null;
  }
  if (_queueManager != null)
  {
  _queueManager.Disconnect();
  _queueManager.Close();
  _queueManager = null;
  }

これに伴う問題は、SQLデータベースでの作業がコミットされている間、アプリケーションが閉じられた後、すべてのメッセージがキューに再表示されることです。トランザクションスコープ内で例外が発生した場合、MQのメッセージが削除されたままであるように見える間(アプリケーションを再起動するまで)、SQLトランザクションはロールバックします。また、.NETクライアントとMQサーバーの間にDTCアクティビティが表示されません(予想されますか?)

私はここでちょっと迷っています、どんな助けでも大歓迎です。

  • どのMQクライアントを使用する必要がありますか?マネージド、アンマネージド、XA?
  • DTCアクティビティを表示する必要がありますか?管理対象クライアントを参加させるにはどうすればよいですか?
  • トランザクションスコープ内に作成する必要があるオブジェクトはどれですか?
  • トランザクションスコープをコミットしても、アプリケーションが終了するとメッセージがキューに再表示されるのはなぜですか?

アップデート

  • 私はこれをクライアントとサーバーの両方で7.1で動作させてきましたが、その(サーバー)バージョンを本番環境にデプロイするには時間がかかりすぎます。
  • したがって、サーバー側でバージョン7.0.xを使用する必要があり、クライアント側では必要なものを何でも使用できます。
  • 7.1クライアントを使用したMQ6サーバーへの接続は、エラーコード2354で失敗します
4

1 に答える 1

4

TransactionScopeを使用して完全管理モードでグローバル・トランザクションを実行するには、少なくともWebSphere MQ v7.1(クライアントとキュー・マネージャーの両方)がインストールされている必要があります。この場合、MSDTCがトランザクションコーディネーターになります。あなたが投稿したInfoCenterリンクは、実際にはWebSphereMQv7.1を指しています。

更新:
MQ v7.1より前では、XAトランザクションは、トランザクションコーディネーターとしてMTSを使用するアンマネージモードでのみサポートされていました。アンマネージドモードでの分散トランザクションのサンプルコードはこちらです。追加のコンポーネントであるExtendedTransactionClient(XTC)をインストールする必要があります。最新の発表によると、XTCは無料で利用できます。インストール可能なものは、MQサーバーのインストールイメージにあります。

MQ接続が切断されると(基本的にMQDISCが呼び出されます)、トランザクション内のコミットされていないメッセージはすべてロールバックされます。このため、メッセージはキューに再表示されます。

于 2012-10-24T17:09:35.833 に答える