For more information about the JMS classes described in this section, access the latest JMS Specification and Javadoc supplied on the Java Web site at the following location:
A transaction enables an application to coordinate a group of messages for production and consumption, treating messages sent or received as an atomic unit.
When an application commits a transaction, all of the messages it received within the transaction are removed from the messaging system and the messages it sent within the transaction are delivered. If the application rolls back the transaction, then the messages it received within the transaction are returned to the messaging system and messages it sent are discarded.
When a topic subscriber rolls back a received message, the message is redelivered to that subscriber. When a queue receiver rolls back a received message, the message is redelivered to the queue, not the consumer, so that another consumer on that queue can receive the message.
For example, when shopping online, you select items and store them in an online shopping cart. Each ordered item is stored as part of the transaction, but your credit card is not charged until you confirm the order by checking out. At any time, you can cancel your order and empty your cart, rolling back all orders within the current transaction.
There are three ways to use transactions with JMS:
If you are using only JMS in your transactions, you can create a JMS transacted session.
If you are mixing other operations, such as EJB, with JMS operations, you should use a Java Transaction API (JTA) user transaction in a non-transacted JMS session.
Use message driven beans.
The following sections explain how to use a JMS transacted session and JTA user transaction.
When using transactions, it is recommended that you define a session exception listener to handle any problems that occur before a transaction is committed or rolled back, as described in Defining a Connection Exception Listener.
acknowledge() method is called within a transaction, then it is ignored. If the recover() method is called within a transaction, a
JMSException is thrown.
A JMS transacted session supports transactions that are located within the session. A JMS transacted session's transaction will not have any effect outside of the session. For example, rolling back a session will roll back all sends and receives on that session, but will not roll back any database updates. JTA user transactions are ignored by JMS transacted sessions.
Transactions in JMS transacted sessions are started implicitly, after the first occurrence of a send or receive operation, and chained together; whenever you commit or roll back a transaction, another transaction automatically begins.
Before using a JMS transacted session, the system administrator should adjust the connection factory (Transaction Timeout) and/or session pool (Transaction) attributes, as necessary for the application development environment.
Figure 13-1 shows the steps required to set up and use a JMS transacted session.
Figure 13-1 Setting Up and Using a JMS Transacted Session
Set up the JMS application as described in Setting Up a JMS Application, when creating sessions, as described in Step 3: Create a Session Using the Connection, specify that the session is to be transacted by setting the
transacted Boolean value to
For example, the following methods show how to create a transacted session for the point-to-point and Publish/subscribe messaging models, respectively:
qsession = qcon.createQueueSession( true, Session.AUTO_ACKNOWLEDGE ); tsession = tcon.createTopicSession( true, Session.AUTO_ACKNOWLEDGE );
After a session is defined, you can determine whether or not a session is transacted using the following session method:
public boolean getTransacted( ) throws JMSException
The acknowledge value is ignored for transacted sessions.
Perform the desired operations associated with the current transaction.
After you have performed the desired operations, execute one of the following methods to commit or roll back the transaction.
To commit the transaction, execute the following method:
public void commit( ) throws JMSException
commit() method commits all messages sent or received during the current transaction. Sent messages are made visible, while received messages are removed from the messaging system.
To roll back the transaction, execute the following method:
public void rollback( ) throws JMSException
rollback() method cancels any messages sent during the current transaction and returns any messages received to the messaging system.
If either the
rollback() methods are issued outside of a JMS transacted session, then a
IllegalStateException is thrown.
The Java Transaction API (JTA) supports transactions across multiple data resources. JTA is implemented as part of WebLogic Server and provides a standard Java interface for implementing transaction management.
You program your JTA user transaction applications using the
javax.transaction.UserTransaction object, described at
http://www.oracle.com/technetwork/java/javaee/jta/index.html, to begin, commit, and roll back the transactions. When mixing JMS and EJB within a JTA user transaction, you can also start the transaction from the EJB, as described in Transactions in EJB Applications in Developing JTA Applications for Oracle WebLogic Server.
You can start a JTA user transaction after a transacted session has been started; however, the JTA transaction will be ignored by the session and vice versa.
WebLogic Server supports the two-phase commit protocol (2PC), enabling an application to coordinate a single JTA transaction across two or more resource managers. It guarantees data integrity by ensuring that transactional updates are committed in all of the participating resource managers, or are fully rolled back out of all the resource managers, reverting to the state before the start of the transaction.
Before using a JTA transacted session, the system administrator must configure the connection factories to support JTA user transactions by selecting the XA Connection Factory Enabled check box.
Figure 13-2 shows the steps required to set up and use a JTA user transaction.
Figure 13-2 Setting Up and Using a JTA User Transaction
Set up the JMS application as described in Setting Up a JMS Application, however, when creating sessions, as described in Step 3: Create a Session Using the Connection, specify that the session is to be non-transacted by setting the
transacted boolean value to
For example, the following methods illustrate how to create a non-transacted session for the PTP and Pub/sub messaging models, respectively.
qsession = qcon.createQueueSession( false, Session.AUTO_ACKNOWLEDGE ); tsession = tcon.createTopicSession( false, Session.AUTO_ACKNOWLEDGE );
When a user transaction is active, the acknowledge mode is ignored.
The application uses JNDI to return an object reference to the
UserTransaction object for the WebLogic Server domain.
You can look up the
UserTransaction object by establishing a JNDI context (
context) and executing the following code, for example:
UserTransaction xact = ctx.lookup("javax.transaction.UserTransaction");
Start the JTA user transaction using the
UserTransaction.begin() method. For example:
Perform the desired operations associated with the current transaction.
Once you have performed the desired operations, execute one of the following
rollback() methods on the
UserTransaction object to commit or roll back the JTA user transaction.
To commit the transaction, execute the following
commit() method causes WebLogic Server to call the Transaction Manager to complete the transaction, and commit all operations performed during the current transaction. The Transaction Manager is responsible for coordinating with the resource managers to update any databases.
To roll back the transaction, execute the following
rollback() method causes WebLogic Server to call the Transaction Manager to cancel the transaction, and roll back all operations performed during the current transactions.
Once you call the
rollback() method, you can optionally start another transaction by calling
Because JMS cannot determine which, if any, transaction to use for an asynchronously delivered message, JMS asynchronous message delivery is not supported within JTA user transactions.
However, message— driven beans provide an alternative approach. A message driven bean can automatically begin a user transaction just before message delivery.
For information about using message— driven beans to simulate asynchronous message delivery, see Designing Message-Driven EJBs in Developing Enterprise JavaBeans, Version 2.1, for Oracle WebLogic Server.
The following example shows the steps to set up an application for mixed EJB and JMS operations in a JTA user transaction by looking up a
javax.transaction.UserTransaction using JNDI, and beginning and then committing a JTA user transaction. In order for this example to run, the XA Connection Factory Enabled check box must be selected when the system administrator configures the connection factory.
In addition to this simple JTA User Transaction example, see example provided with WebLogic JTA, located in the
\wl_server\examples\src\examples\jta\jmsjdbc directory, where
EXAMPLE_HOME represents the directory in which the WebLogic Server code examples are configured.
Import the appropriate packages, including the
javax.transaction.UserTransaction package, at
import java.io.*; import java.util.*; import javax.transaction.UserTransaction; import javax.naming.*; import javax.jms.*;
Define the required variables, including the JTA user transaction variable.
public final static String JTA_USER_XACT= "javax.transaction.UserTransaction"; . . .
Set up the JMS application, creating a non-transacted session. For more information on setting up the JMS application, refer to Setting Up a JMS Application.
//JMS application setup steps including, for example: qsession = qcon.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
Look up the
UserTransaction using JNDI.
UserTransaction xact = (UserTransaction) ctx.lookup(JTA_USER_XACT);
Perform the desired operations.
// Perform some JMS and EJB operations here.
You must correctly configure either the Cross— Domain Security or Security Interoperability Mode for all participating domains.
Keep all the domains used by your process symmetric with respect to Cross Domain Security configuration and Security Interoperability Mode. Because both settings are set at the domain level, it is possible for a domain to be in a mixed mode, meaning the domain has both Cross Domain Security and Security Interoperability Mode set. For more information, see Configuring Secure Inter-Domain and Intra-Domain Transaction Communication in Developing JTA Applications for Oracle WebLogic Server.