| CONTENTS | PREV | NEXT | INDEX | Designing Enterprise Applications with the J2EETM Platform, Second Edition |
Servlets and JSP pages in a two-tier application can access enterprise information systems within the scope of a JTA transaction. Servlets and JSP pages support only programmatic transaction demarcation. A servlet or JSP page can use JNDI to look up a UserTransaction object (using the standard defined name java:comp/UserTransaction), and then use the UserTransaction interface to demarcate transactions.
Code Example 8.1 illustrates the use of the JTA UserTransaction interface to demarcate transactions within a Servlet:
Context ic = new InitialContext();
UserTransaction ut =
(UserTransaction) ic.lookup("java:comp/UserTransaction");
ut.begin();
// access resources transactionally here
ut.commit();
| Code Example 8.1 Web Component Using a JTA Transaction |
Calling UserTransaction.begin associates the calling thread with a new transaction context. Subsequent accesses of transactional resources such as JDBC connections or resource adapter connections implicitly enlist those resources into the transaction. The call to UserTransaction.commit commits the transaction, transparently engaging the two-phase commit protocol if necessary.
A servlet or JSP page may start a transaction only in its service method. A transaction that is started by a servlet or JSP page must be completed before the service method returns; in other words, transactions may not span Web requests. If the service method returns with a pending UserTransaction (that is, begin has been called, but not commit or rollback), the container aborts the transaction and rolls back all data updates. JTA transactions are not supported in servlet filters and Web application event listeners.
In a multitier environment, data presentation and user interaction are the primary responsibilities of servlets and JSP pages. Data presentation and user interaction are usually not transactional operations. Because transactions tend to be associated with business logic, database access and other transactional work should be handled by transactional enterprise beans instead of by the JTA in the Web tier.
In designs that do not use enterprise beans, or where for some reason you choose to use Web tier transactions, the following guidelines apply. JTA transactions, threads, and transactional resources (for example, JDBC connections) have many complex and subtle interactions. Web components should follow the guidelines stated in the transaction management chapter of the J2EE specification (version 1.3, section J2EE.4.2):
- JTA transactions must be started and completed only from the thread in which the
servicemethod is called. If the Web component creates additional threads for any purpose, these threads must not attempt to start JTA transactions. These additional threads will not be associated with any JTA transaction.- Transactional resources such as JDBC connections acquired and released by threads other than the
servicemethod thread should not be shared between threads.- Transactional resource objects should not be stored in static fields.
- Web components that implement
SingleThreadModelmay store references to transactional resources in class instance fields. By definition, only one thread can ever access an instance of a Web component implementingSingleThreadModel; therefore, that instance can assume that fields referencing any transactional resources will not be shared with any other thread.- Web components that do not implement
SingleThreadModelshould not store transactional resource objects in class instance fields. Transactional resource objects for such components should be acquired and released within the same invocation of theservicemethod.