216 lines
8.0 KiB
HTML
216 lines
8.0 KiB
HTML
<!--
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
-->
|
|
|
|
<html>
|
|
<head>
|
|
<title>ActiveMQ Artemis JMS XA Send Example</title>
|
|
<link rel="stylesheet" type="text/css" href="../common/common.css" />
|
|
<link rel="stylesheet" type="text/css" href="../common/prettify.css" />
|
|
<script type="text/javascript" src="../common/prettify.js"></script>
|
|
</head>
|
|
<body onload="prettyPrint()">
|
|
<h1>JMS XA Send Example</h1>
|
|
<p>This example shows you how message sending behaves in an XA transaction in ActiveMQ Artemis. When a message is sent within
|
|
the scope of an XA transaction, it will only reach the queue once the transaction is committed.
|
|
If the transaction is rolled back the sent messages will be discarded by the server.</p>
|
|
|
|
<p>ActiveMQ Artemis is JTA aware, meaning you can use ActiveMQ Artemis in a XA transactional environment
|
|
and participate in XA transactions. It provides the javax.transaction.xa.XAResource interface for that
|
|
purpose. Users can get a XAConnectionFactory to create XAConnections and XASessions.</p>
|
|
|
|
<p>In this example we simulate a transaction manager to control the transactions. First we create an XASession
|
|
and enlist it in a transaction through its XAResource. We then send two words, 'hello' and 'world', with
|
|
the session, let the transaction roll back. The messages are discarded and never be received. Next we start
|
|
a new transaction with the same XAResource, but this time we commit the transaction. Both messages are received.</p>
|
|
|
|
<h2>Example step-by-step</h2>
|
|
<p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p>
|
|
|
|
<ol>
|
|
<li>First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the <code>client-jndi.properties</code> file in the directory <code>../common/config</code></li>
|
|
<pre class="prettyprint">
|
|
<code>InitialContext initialContext = getContext(0);</code>
|
|
</pre>
|
|
|
|
<li>We look-up the JMS queue object from JNDI</li>
|
|
<pre class="prettyprint">
|
|
<code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code>
|
|
</pre>
|
|
|
|
<li>We perform a lookup on the XA Connection Factory</li>
|
|
<pre class="prettyprint">
|
|
<code>XAConnectionFactory cf = (XAConnectionFactory) initialContext.lookup("/XAConnectionFactory");</code>
|
|
</pre>
|
|
|
|
<li>We create a JMS XAConnection</li>
|
|
<pre class="prettyprint">
|
|
<code>connection = cf.createXAConnection();</code>
|
|
</pre>
|
|
|
|
<li>We Start the connection</li>
|
|
<pre class="prettyprint">
|
|
<code>connection.start();</code>
|
|
</pre>
|
|
|
|
<li>We create a JMS XASession</li>
|
|
<pre class="prettyprint">
|
|
<code>XASession xaSession = connection.createXASession();</code>
|
|
</pre>
|
|
|
|
<li>We create a normal session</li>
|
|
<pre class="prettyprint">
|
|
<code>Session normalSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code>
|
|
</pre>
|
|
|
|
<li>We create a normal Message Consumer</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
MessageConsumer normalConsumer = normalSession.createConsumer(queue);
|
|
normalConsumer.setMessageListener(new SimpleMessageListener());
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We get the JMS Session</li>
|
|
<pre class="prettyprint">
|
|
<code>Session session = xaSession.getSession();</code>
|
|
</pre>
|
|
|
|
<li>We create a message producer</li>
|
|
<pre class="prettyprint">
|
|
<code>MessageProducer producer = session.createProducer(queue);</code>
|
|
</pre>
|
|
|
|
<li>We create two Text Messages</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
TextMessage helloMessage = session.createTextMessage("hello");
|
|
TextMessage worldMessage = session.createTextMessage("world");
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We create a transaction</li>
|
|
<pre class="prettyprint">
|
|
<code>Xid xid1 = new XidImpl("xa-example1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());</code>
|
|
</pre>
|
|
|
|
<li>We get the JMS XAResource</li>
|
|
<pre class="prettyprint">
|
|
<code>XAResource xaRes = xaSession.getXAResource();</code>
|
|
</pre>
|
|
|
|
<li>We begin the Transaction work</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.start(xid1, XAResource.TMNOFLAGS);</code>
|
|
</pre>
|
|
|
|
<li>We do work, sending two messages.</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
producer.send(helloMessage);
|
|
producer.send(worldMessage);
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We check the result, it should receive none!</li>
|
|
<pre class="prettyprint">
|
|
<code>checkNoMessageReceived();</code>
|
|
</pre>
|
|
|
|
<li>We stop the work</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.end(xid1, XAResource.TMSUCCESS);</code>
|
|
</pre>
|
|
|
|
<li>We prepare</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.prepare(xid1);</code>
|
|
</pre>
|
|
|
|
<li>We roll back the transaction </li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.rollback(xid1);</code>
|
|
</pre>
|
|
|
|
<li>We check no messages should be received! </li>
|
|
<pre class="prettyprint">
|
|
<code>checkNoMessageReceived();</code>
|
|
</pre>
|
|
|
|
<li>We create another transaction</li>
|
|
<pre class="prettyprint">
|
|
<code>Xid xid2 = new XidImpl("xa-example2".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());</code>
|
|
</pre>
|
|
|
|
<li>We start the transaction</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.start(xid2, XAResource.TMNOFLAGS);</code>
|
|
</pre>
|
|
|
|
<li>We re-send those messages</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
producer.send(helloMessage);
|
|
producer.send(worldMessage);
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We stop the work</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.end(xid2, XAResource.TMSUCCESS);</code>
|
|
</pre>
|
|
|
|
<li>We prepare</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.prepare(xid2);</code>
|
|
</pre>
|
|
|
|
<li>We check that no messages should be received at this moment</li>
|
|
<pre class="prettyprint">
|
|
<code>checkNoMessageReceived();</code>
|
|
</pre>
|
|
|
|
<li>We commit!</li>
|
|
<pre class="prettyprint">
|
|
<code>xaRes.commit(xid2, false);</code>
|
|
</pre>
|
|
|
|
<li>We check that all messages are received.</li>
|
|
<pre class="prettyprint">
|
|
<code>checkAllMessageReceived();</code>
|
|
</pre>
|
|
|
|
<li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li>
|
|
|
|
<pre class="prettyprint">
|
|
<code>finally
|
|
{
|
|
if (initialContext != null)
|
|
{
|
|
initialContext.close();
|
|
}
|
|
if (connection != null)
|
|
{
|
|
connection.close();
|
|
}
|
|
}</code>
|
|
</pre>
|
|
</ol>
|
|
</body>
|
|
</html>
|