This example shows how to use a queue and a topic in a single transaction
as well as how to pass a session to a message listener’s constructor
function. The program represents a highly simplified e-commerce application
in which the following things happen.

A retailer sends a MapMessage to the vendor
order queue, ordering a quantity of computers, and waits for the vendor’s
reply:

The vendor receives the retailer’s order message and
sends an order message to the supplier order topic in one transaction. This
JMS transaction uses a single session, so you can combine a receive from a
queue with a send to a topic. Here is the code that uses the same session
to create a consumer for a queue and a producer for a topic:

Each supplier receives the order from the order topic, checks
its inventory, and then sends the items ordered to the queue named in the
order message’s JMSReplyTo field. If it does not
have enough in stock, the supplier sends what it has. The synchronous receive
from the topic and the send to the queue take place in one JMS transaction.

The vendor receives the replies from the suppliers from its
confirmation queue and updates the state of the order. Messages are processed
by an asynchronous message listener; this step shows the use of JMS transactions
with a message listener.

Figure 31–10 Transactions: JMS Client Example

The program contains five classes: Retailer, Vendor, GenericSupplier, VendorMessageListener,
and Order. The program also contains a main method
and a method that runs the threads of the Retailer, Vendor, and two supplier classes.

All the messages use the MapMessage message type.
Synchronous receives are used for all message reception except for the case
of the vendor processing the replies of the suppliers. These replies are processed
asynchronously and demonstrate how to use transactions within a message listener.

At random intervals, the Vendor class throws an exception
to simulate a database problem and cause a rollback.

All classes except Retailer use transacted sessions.

The program uses three queues named jms/AQueue, jms/BQueue, and jms/CQueue, and one topic named jms/OTopic.

Before you run the program, do the following:

In a terminal window, go to the following directory:

tut-install/javaeetutorial5/examples/jms/advanced/transactedexample/

Create the necessary resources using the following command:

ant create-resources

This command creates three destination resources with the names jms/AQueue, jms/BQueue, and jms/CQueue,
all of type javax.jms.Queue, and one destination resource
with the name jms/OTopic, of type javax.jms.Topic.

To compile and package the program using NetBeans IDE,
follow these steps:

In NetBeans IDE, choose Open Project from the File menu.

In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jms/advanced/.

Select the transactedexample folder.

Select the Open as Main Project check box.

Click Open Project.

Right-click the project and choose Build.

To compile and package the program using Ant, follow these
steps:

Go to the following directory:

tut-install/javaeetutorial5/examples/jms/advanced/transactedexample/

Type the following command:

ant

To run the program using NetBeans IDE, follow these steps:

Right-click the transactedexample project
and choose Properties.

Select Run from the Categories tree.

In the Arguments field, type a number that specifies the number
of computers to order:

3

Click OK.

Right-click the project and choose Run.

To run the program from the command line, follow these steps:

Go to the dist directory:

cd dist

Use a command like the following to run the program. The argument
specifies the number of computers to order:

After you run the program, you can delete the physical destinations
and the destination resources. Go to the directory tut-install/javaeetutorial5/examples/jms/advanced/transactedexample/ and type the following command: