5

私の目的は、WebSphere MQ Javaプログラミングを使用して、n個のメッセージをforループに入れてWebSphereMQキューに入れることです。

私のJavaプログラムはスタンドアロンプ​​ログラムとして実行されます。

間に例外がある場合は、すべてのメッセージをロールバックする必要があります。

例外がなければ、すべてのメッセージをコミットする必要があります。

私が完全に完了するまで、外の世界は私のメッセージをキューに入れるべきではありません。どうすればこれを達成できますか?

T.Robからの返信に従ってサンプルコードで更新:

サンプルコードに問題がないか確認してください。

MQGMO_SYNCPOINTの設定は、私のプログラムの呼び出しにのみ関連していますか?(並列で実行されている同様のプログラムも同じキューにメッセージを配置し、それらのメッセージが私のプログラムのSYNCPOINTの影響を受けないようにするためです。)

public void sendMsg() {
        MQQueue queue = null;
        MQQueueManager queueManager = null;
        MQMessage mqMessage = null;
        MQPutMessageOptions pmo = null;
        System.out.println("Entering..");
        try {
            MQEnvironment.hostname = "x.x.x.x";
            MQEnvironment.channel = "xxx.SVRCONN";
            MQEnvironment.port = 9999;


            queueManager = new MQQueueManager("XXXQMANAGER");
            int openOptions = MQConstants.MQOO_OUTPUT;      
            queue = queueManager.accessQueue("XXX_QUEUENAME", openOptions, null, null, null);

            pmo = new MQPutMessageOptions(); 
            pmo.options = CMQC.MQGMO_SYNCPOINT;


            String input = "testing";
            System.out.println("sending messages....");
            for (int i = 0; i < 10; i++) {
                input = input + ": " + i;
                mqMessage = new MQMessage();
                mqMessage.writeString(input);
                System.out.println("Putting message: " + i);
                queue.put(mqMessage, pmo);

            }
            queueManager.commit();
            System.out.println("Exiting..");

        } catch (Exception e) {
            e.printStackTrace();
            try {
                System.out.println("rolling back messages");
                if (queueManager != null)
                    queueManager.backout();
            } catch (MQException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                if (queue != null)
                    queue.close();
                if (queueManager != null)
                    queueManager.close();
            } catch (MQException e) {
                e.printStackTrace();
            }
        }
    }
4

3 に答える 3

5

WMQは、ローカルとグローバル(XA)の両方の作業単位をサポートします。オプションを指定するだけで、ローカルの作業単位を使用できます。別の回答でkeithkreisslが述べているように、グローバルXAトランザクションにはトランザクションマネージャーが必要です。

あなたが説明したことについて、同期点の下でメッセージングを行うPOJOは、で指定MQC.MQGMO_SYNCPOINTしますMQGetMessageOptions。コミットする準備ができたら、MQQManager.commit()またはを発行しMQQManager.backout()ます。

ggrandesによって提供される応答とドキュメントは、JavaクラスではなくJMSを参照していることに注意してください。Javaクラスは、WMQ手続き型APIと同等のJavaを使用し、多くのスレッド(doc)をサポートし、接続プール(doc)を提供することもできます。正しい動作については、JMSドキュメントではなくJavaドキュメントを参照してください。また、最新のWMQJavaV7.5クライアントに付属するWMQV7.5のドキュメントにリンクしました。後のクライアントには、より多くのローカル機能(トレース、柔軟なインストールパス、MQClient.iniなど)があり、バックレベルのQMgrと連携します。最新のクライアントを使用することを強くお勧めします。ダウンロードは無料です。

于 2013-01-20T21:59:48.110 に答える
3

トランザクションを有効にしてセッションを作成するだけで済みます。

Session session;
// ...
boolean transacted = true;
session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
try {
    // ...do things...
    session.commit();
} catch (Exception e) {
    session.rollback();
}
// ...

警告-注:セッションはスレッドセーフではありません;-)

于 2013-01-20T17:10:30.017 に答える
1

トランザクションマネージャーにアクセスでき、さらに重要なことに、MQアクセスに接続されたXATransactionがある場合は、メッセージ処理の開始時にトランザクションを開始して、すべてのメッセージをキューに入れ、トランザクションをコミットできます。XATransactionsを使用すると、トランザクションがコミットされるまでメッセージは送信されません。アクセスできない場合は、メッセージをローカルデータオブジェクトに配置し、メッセージを送信するローカルデータオブジェクトで例外が繰り返されない場合は、コードをtry / catchでラップすることで、もう少し配管を行うことができます。後者のアプローチの問題は、他のすべての処理がコミットされることですが、メッセージの送信で問題が発生した場合、他の処理はロールバックされません。

于 2013-01-20T16:42:29.470 に答える