web server - Borland Technical Publications

web server - Borland Technical Publications web server - Borland Technical Publications

techpubs.borland.com
from techpubs.borland.com More from this publisher
12.11.2014 Views

JMS and Transactions sessions on behalf of a bean, the parameters of the createQueueSession(boolean transacted,int acknowledgeMode) and createTopicSession(boolean transacted, int acknowledgeMode) methods are ignored. It is recommended that the Bean Provider specify that a session is transacted, but provide 0 for the value of the acknowledgment mode. The Bean Provider should not use the JMS acknowledge() method either within a transaction or within an unspecified transaction context. Message acknowledgment in an unspecified transaction context is handled by the container. Section 17.6.5 describes some of the techniques that the container can use for the implementation of a method invocation with an unspecified transaction context. Avoiding use of the JMS request/reply paradigm and JMS acknowledge() method is equally relevant for other J2EE components such as application clients, as it is to EJB bean code. In addition to rules described above, application code should not use any JMS XA APIs. The program should look exactly as if the code is written in a nontransactional JMS program. It is the Container's responsibility to handle any XA handshakes required when a global transaction is active. The only configuration required is that deployment descriptor element , with reference to the JMS Connection factory JNDI object, be set up to use the XA variant. If it is non-XA, the program still runs, but there are no atomicity guarantees, in other words, it is a local transaction. Also note that for BES to automatically handle the transaction handshakes it is necessary to have the application run in a Container, either EJB, Web or appclient. For example, a java client with no JMS XA API calls will not have its JMS activity participate in a global transaction, one has to write it as a J2EE application client instead. Also make sure that all connection factories are looked up through deployment descriptor element . This allows the Container to trap the JMS API calls and insert appropriate hooks. Lets examine in more detail the following sentences extracted from the EJB 2.0 specification: Because the container manages the transactional enlistment of JMS sessions on behalf of a bean, the parameters of the createQueueSession(boolean transacted,int acknowledgeMode) and createTopicSession(boolean transacted, int acknowledgeMode) methods are ignored. It is recommended that the Bean Provider specify that a session is transacted, but provide 0 for the value of the acknowledgment mode. The assumption here is that messages produced/consumed by JMS sessions should be included as part of the unit of work maintained by a global transaction, should a global transaction be active. In order for transactional enlistment to occur, the parent connection factory of connections on which createQueueSession() or createTopicSession() are invoked must be defined as a javax.jms.XAQueueConnectionFactory or javax.jms.XATopicConnectionFactory, respectively. That is, the value for of J2EE deployment descriptor element , with definition of JMS connection factory to be used for the J2EE component, must be either javax.jms.XAQueueConnectionFactory or javax.jms.XATopicConnectionFactory. If the connection factory has a non XA connection factory , the program still runs but work performed on JMS sessions will not be included in the global transaction; in this case the transacted and acknowledgeMode parameters will influence the behavior of message production/consumption. Chapter 23: Using JMS 217

JMS and Transactions For instance: import javax.jms.*; QueueConnectionFactory nonXAQCF; Queue myQueue; try { javax.naming.Context ctx = (javax.naming.Context) new javax.naming.InitialContext(); nonXAQCF = (QueueConnectionFactory) ctx.lookup("java:comp/env/jms/ MyJMSQueueConnectionFactory"); myQueue = (Queue) ctx.lookup("java:comp/env/jms/MyJMSQueue"); } catch (javax.naming.NamingException exp) { exp.printStackTrace(); } // Note: A global transaction context is currently active when the Session is being created QueueSession qSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); QueueSender = qSession.createSender(myQueue); TextMessage msg = qSession.createTextMessage("A Message "); sender.send(msg); Here, the TextMessage msg is queued regardless of the outcome of the active global transaction. This is in line with test cases in the J2EE Compatibility Test Suite (CTS 1.3.1). It seems useful to have this capability in a global transaction, whereby a log message needs to be sent irrespective of the enclosing global transaction's completion result. Multiple resource access within a single global transaction is supported in BES. This provides the capability to do a unit of work which is composed of sending/receiving JMS messages along with some other type of resource manager access. That is, it is desirable to write code (in an EJB for example) which does some work against a non JMS resource such as a database and also send a message to a queue with the Container providing transactional completion for all work performed. Upon completion of the transaction, either the work performed against the database is committed AND the message is queued, or should something fail during the transaction database work is rolled back AND the message is not delivered to the queue. In application code, an EJB method such as doSomeWork() shown below is supported in BES: // Business method in a session bean, the EJB container marks the transaction void doSomeWork() { // Establish a database connection java.sql.Connection dbConn = datasource.getConnection(); // Execute SQL ... } // Call a remote EJB in the same transaction ejbRemote.doWork(); // Send a JMS message to a queue jmsSender.send(msg); 218 BES Developer’s Guide

JMS and Transactions<br />

sessions on behalf of a bean, the parameters of the createQueueSession(boolean<br />

transacted,int acknowledgeMode) and createTopicSession(boolean transacted, int<br />

acknowledgeMode) methods are ignored. It is recommended that the Bean Provider<br />

specify that a session is transacted, but provide 0 for the value of the<br />

acknowledgment mode.<br />

The Bean Provider should not use the JMS acknowledge() method either within a<br />

transaction or within an unspecified transaction context. Message acknowledgment in<br />

an unspecified transaction context is handled by the container. Section 17.6.5<br />

describes some of the techniques that the container can use for the implementation<br />

of a method invocation with an unspecified transaction context.<br />

Avoiding use of the JMS request/reply paradigm and JMS acknowledge() method is<br />

equally relevant for other J2EE components such as application clients, as it is to EJB<br />

bean code. In addition to rules described above, application code should not use any<br />

JMS XA APIs. The program should look exactly as if the code is written in a nontransactional<br />

JMS program. It is the Container's responsibility to handle any XA<br />

handshakes required when a global transaction is active. The only configuration<br />

required is that deployment descriptor element , with reference to the<br />

JMS Connection factory JNDI object, be set up to use the XA variant. If it is non-XA,<br />

the program still runs, but there are no atomicity guarantees, in other words, it is a local<br />

transaction. Also note that for BES to automatically handle the transaction handshakes<br />

it is necessary to have the application run in a Container, either EJB, Web or appclient.<br />

For example, a java client with no JMS XA API calls will not have its JMS activity<br />

participate in a global transaction, one has to write it as a J2EE application client<br />

instead. Also make sure that all connection factories are looked up through deployment<br />

descriptor element . This allows the Container to trap the JMS API calls<br />

and insert appropriate hooks.<br />

Lets examine in more detail the following sentences extracted from the EJB 2.0<br />

specification:<br />

Because the container manages the transactional enlistment of JMS sessions on<br />

behalf of a bean, the parameters of the createQueueSession(boolean transacted,int<br />

acknowledgeMode) and createTopicSession(boolean transacted, int acknowledgeMode)<br />

methods are ignored. It is recommended that the Bean Provider specify that a session<br />

is transacted, but provide 0 for the value of the acknowledgment mode.<br />

The assumption here is that messages produced/consumed by JMS sessions should<br />

be included as part of the unit of work maintained by a global transaction, should a<br />

global transaction be active. In order for transactional enlistment to occur, the parent<br />

connection factory of connections on which createQueueSession() or<br />

createTopicSession() are invoked must be defined as a<br />

javax.jms.XAQueueConnectionFactory or javax.jms.XATopicConnectionFactory,<br />

respectively. That is, the value for of J2EE deployment descriptor element<br />

, with definition of JMS connection factory to be used for the J2EE<br />

component, must be either javax.jms.XAQueueConnectionFactory or<br />

javax.jms.XATopicConnectionFactory. If the connection factory has a non XA connection<br />

factory , the program still runs but work performed on JMS sessions will not<br />

be included in the global transaction; in this case the transacted and acknowledgeMode<br />

parameters will influence the behavior of message production/consumption.<br />

Chapter 23: Using JMS 217

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!