Section 16.4. EJB Transaction Management


16.4. EJB Transaction Management

In this section, we discuss some extended topics related to transaction management with EJB components. This material complements the introductory section on EJB transaction management found in Chapter 6. If you are specifically concerned with transaction management related to EJBs , we recommend that you read "Transaction Management" in Chapter 6 since it introduces the basic concepts and some general rules related to both declarative and programmatic transaction management within EJBs. Once you have that material under your belt, if you feel you need to know more, come back to this section for additional coverage.

If you're using strictly declarative transaction management within EJBs, this is referred to as Container-Managed Transaction Demarcation (CMTD). The container is responsible for starting and committing or rolling back the transactions required by the EJB based on the directives specified in the deployment descriptor as well as some programmatic hints by the developer in the EJB code. The container leverages JTA for the transaction management under the covers.

Using programmatic transaction management within EJB components is a bit of a special case, because the EJB container has a default assumption that it is managing transactions on behalf of its components. Programmatic transaction management within EJB components is sometimes referred to as Bean-Managed Transaction Demarcation (BMTD ). If an EJB developer chooses to use BMTD in a bean, then the bean is responsible for transaction operations. The transaction operations can be performed through resource-specific APIs such as JDBC and JMS, or they can be done explicitly using JTA. When BMTD is in use, the container's transaction manager still handles all the two-phase commit issues related to distributed transactions that we discussed earlier, but it assumes that the application code is handling the start, commit, and rollback of transactions. As mentioned in Chapter 6, BMTD is not allowed for entity beans, even those that manage their own persistence.

16.4.1. BMTD with JTA

Using bean-managed transaction management doesn't necessarily mean that you are using JTA calls in your EJB code. You could simply be using specific resource manager APIs, like JDBC or Hibernate for databases or JMS for message servers. But if you do find the need to access and use a JTA UserTransaction from your BMTD beans (or use any other aspects of the JTA, for that matter), you need to consider a few things.

As we saw in Example 16-1, you can obtain the JTA transaction from the JNDI context of the EJB container. EJB also allows you to access the UserTransaction using the getUserTransaction( ) method of the javax.ejb.EJBContext, as shown in Example 16-2 for a session EJB.

Example 16-2. Accessing the UserTransaction from the EJBContext
 SessionContex mSessionContext = . . .; UserTransaction aUserTransaction = mSessionContext.getUserTransaction( ); // Now use the UserTransaction to begin/commit/roll back transactions . . . 

If you use BMTD in your bean, it's important to be mindful of how the container is going to manage clients that make requests of your EJB from within their own transactions. If the client starts its own transaction and invokes business methods on your BMTD bean, the EJB container will automatically suspend the client's transaction during the request. Once the request completes, the client's transaction is resumed. So if your EJB performs no JTA operations during the request, the entire request operates without any transaction context. But if your EJB starts a new transaction by calling the begin( ) method on a UserTransaction, a new transaction is started and the request is processed under this new transaction context.

Since you are using the JTA API to manage transaction boundaries, the specification prohibits invoking resource-specific APIs. The EJB specification prohibits invoking the commit( ) or rollback( ) methods of the java.sql.Connection interface. Similarly, you are not allowed to invoke the commit( ) and rollback( ) methods of the javax.jms.Session interface.

The specification also prohibits the getrollbackOnly( ) and the setRollbackOnly( ) methods of javax.ejb.EJBContext, because they are related to CMTD, not BMTD.

In addition to these general behaviors and rules for BMTD beans, there are some special caveats related to BMTD for particular types and subtypes of EJBs.

16.4.1.1. Stateless session beans and message-driven beans

Since a stateless session bean by definition does not maintain state information on behalf of the client, a transaction is not allowed to span methods of a stateless bean. The bean method that starts a transaction must complete the transaction by calling the commit( ) method or the rollback( ) method. If you fail to do so, the container rolls back the transaction, discards the stateless bean instance, and throws an appropriate exception back to the client (java.rmi.RemoteException for remote clients, javax.ejb.EJBException for local clients).

This rule also applies to message-driven beans. If you start a transaction in the onMessage( ) method of a message-driven bean with BMTD, you must call the commit( ) method or the rollback( ) method within the onMessage( ) method to complete the transaction. Otherwise, the container rolls back the transaction and discards the instance of the bean. No exception is thrown back to the client, obviously, since the client has indirectly invoked the bean by sending a message to a JMS destination.

16.4.1.2. Stateful session beans

The behavior of BMTD with a stateful session bean is a bit more involved. Unlike a stateless session bean, a transaction started in one method can be left active at the end of the method, and it remains associated with the stateful session bean instance across subsequent method calls. The transaction remains in effect for the bean until the commit( ) method or the rollback( ) method is called. As mentioned earlier in this section, a container will always suspend any client transactions during requests to BMTD beans. So as long as the transaction started by the bean remains active, all requests made by clients will operate under this transaction context, until it is committed or rolled back.

16.4.2. Container-Managed Transaction Demarcation (CMTD)

When an EJB is using CMTD , it is prohibited from invoking JTA operations in any contexts in which they might interfere with the container's transaction management activities. A bean with CMTD must not invoke the getUserTransaction( ) method of javax.ejb.EJBContext. If it does, the container will throw a java.lang.IllegalStateException. Additionally, the bean must not invoke any UserTransaction methods from within its business methods, message-listener callbacks, or ejbTimeout( ) callbacks. In these same situations, the bean is forbidden from calling commit( ) or rollback( ) on a JDBC Connection or JMS Session.

16.4.2.1. Inducing rollbacks in CMTD

Although application code is not allowed to directly interfere with transaction management under CMTD, your EJB can induce a transaction rollback by calling the setRollbackOnly( ) method of the javax.ejb.EJBContext. At the end of the transaction, the container automatically rolls back instead of committing the transaction, regardless of the state of the transaction. You can query whether the current transaction has been marked for rollback by calling the getrollbackOnly( ) method of the EJBContext. Calling the getrollbackOnly( ) method can be useful for avoiding expensive chunks of transactional code in your EJB. If the results of the code are going to be rolled back regardless, you can skip the processing then and there.

The container will also roll back a transaction when the EJB code throws a runtime exception. The container catches the runtime exception and rolls back the transaction. Note that the exception must be a runtime exception, not a general application exception. A common runtime exception thrown in these situations is javax.ejb.EJBException.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net