|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
General Java Understanding EJB Transactions
Understanding EJB Transactions
By: Sameer Tyagi
Apr. 1, 2000 12:00 AM
EJB servers are transactional servers that allow developers to concentrate on business logic. The EJB model implements two-phase commits, transaction context propagation and distributed transaction, although it's up to the vendors to decide which technique to use. A transaction is formally defined as an "ACID" (atomic, consistent, isolated, durable) unit of work.
In a distributed environment handling transactions involves coordinating the various databases that participate in the transaction. In the EJB framework the bean developer can simply define the transaction policy for the bean during the deployment process, using declarative statements, and let the container handle all distributed transactions (called bean-demarcated transactions). Alternatively, the developer can take explicit control of transactions (called client-demarcated transactions).
Transactional Scope and Attributes
An enterprise bean can take one of the following six attributes in the deployment descriptor, and the container manages the transactions according to the specified attribute. Transaction attributes can be specified for the entire bean or the bean can be fine-tuned by specifying the attributes for individual methods. 1. TX_NOT_SUPPORTED (see Figure 1): This tells the container to invoke bean methods without a transaction context. If a client invokes a bean method from within a transaction context, the container suspends the association between the transaction and the current thread before invoking the method on the enterprise bean instance. The container then resumes the suspended association when the method invocation returns. The suspended transaction context isn't passed to any enterprise bean objects or resources that are used by this bean method. 2. TX_SUPPORTS (see Figure 2): This tells the container to include the bean or method within the transaction scope in which it is invoked. If a method is part of a transactional scope and it invokes any bean with this attribute, the invoked bean and everything it accesses become a part of the transaction. If the client invokes the bean method without a transaction context, the container invokes the bean method without a transaction context. 3. TX_REQUIRED (see Figure 3): This tells the container that the bean method must be invoked within a transaction scope. If a client invokes a bean method from within a transaction context, the container invokes the bean method within the client transaction context. If a client invokes a bean method without a transaction context, the container creates a new transaction context for the invoked bean. The transaction context is then passed to any beans that are used by this bean method. 4. TX_REQUIRES_NEW (see Figure 4): This tells the container to always invoke the bean method within a new transaction context, regardless of whether the client invokes the method within or without a transaction context. The transaction context is passed to any enterprise bean objects or resources that are used by this bean method. 5. TX_MANDATORY (see Figure 5): This directs the container to always invoke the bean method within the transaction context associated with the client. The difference between this and the TX_REQUIRED attribute is that if the client attempts to invoke the bean method without a transaction context, the container throws the javax.jts.TransactionRequiredException exception. The transaction context is passed to any beans that are used by the invoked bean method. 6. TX_BEAN_MANAGED (see Figure 6): This tells the container that the bean class doesn't have its transactional context managed by the server but it uses JTA, more specifically the javax.jts.UserTransaction, to explicitly manage transaction boundaries. Using this attribute, however, imposes a restriction that the attributes of different methods cannot be mixed; if even one method has this attribute, then all methods must manage transaction on their own. Making a bean transactional is expensive at runtime; since it participates in a transaction and conforms to ACID rules, its services can't be shared during the life of a transaction. Declaring a bean to be TX_NOT_SUPPORTED improves performance and may be desirable for EJBs that provide stateless service as they need to conform to the ACID rules.
Transaction Isolation Levels
Isolation levels aren't new to EJBs; EJB defines these levels based on the ANSI-SQL92 standards. They're mapped in JDBC to the static variables defined in the java.sql.Connection interface. Isolation level, like attributes, can be fine-tuned by specifying them at the method level for EJBs; however, all methods invoked in the same transaction must have the same isolation level.
Client-Demarcated Transactions
public void begin() The UserTransaction.begin() method starts a global transaction and associates a javax.transaction.Transaction with the execution thread. It throws the NotSupportedException when the calling thread is already associated with a transaction and the transaction manager implementation doesn't support nested transactions. The UserTransaction.commit() method completes the transaction. If at this point the transaction needs to be rolled back instead of being committed, the transaction manager does so and throws a RollbackException to indicate it. The UserTransaction.rollback() method undoes any changes made since the start of the transaction and removes the association between the Transaction and the execution thread. Getting Transaction Access
public void doTransaction(String customerName, String password,int This UserTransaction also defines two methods: setRollbackOnly() and getRollbackOnly(). The first method allows the bean to veto a transaction explicitly. Once invoked, the transaction can't be committed by anyone, including the container. The second method remains true if the transaction has been so marked and can be used to avoid further unnecessary work in the method. JTA allows the UserTransaction object to be exposed via JNDI. EJBs shouldn't use this approach as it compromises the "middleware portability"; that is, other EJB servers might not support that approach.
Context ctx = new InitialContext(); With entity beans and stateless session beans, a transaction managed with the UserTransaction must start and end in the same method. The reason is that entity and stateless session bean instances are shared across many clients by instance pooling and instance swapping on the server. Stateful session beans allow the UserTransaction object to span multiple method calls because there's always one instance associated with a client, and it maintains conversational state. This bean state (and state of the transaction) is consistent even when the container makes it undergo an internal activation-passivation cycle to conserve server resources.
public class MyStatefulBean implements SessionBean { Repeated calls to getUserTransaction() in a stateful session bean return a reference to the same UserTransaction object. Its state can be checked using a UserTransaction.getStatus() call. Stateful session beans involve conversational state between method calls. Sometimes it may be desirable to cache this transactional state and postpone database updates. The javax.ejb.SessionSynchronization allows the server to inform a stateful session bean of the various stages in the transaction by invoking callback methods such as:
Exception Handling and Transactions
The first rule, which may sound strange, is that any exception thrown outside the transaction scope causes the transaction to roll back. Consider an example of a client invoking a method called doTransaction() on a stateless session bean called MiddleBean. The bean internally then invokes methods on another stateless session bean called TranstestBean. The required code for these beans and the client can be seen in Listings 1 to 4. The sequence of events that occur as a result of the client call is shown in Figure 7. The two beans are deployed with the transaction attributes shown in Table 2 and what happens as a result of these attributes is summarized in Figure 8. In the first case the transaction context is propagated to the TranstestBean bean. When the exception is thrown in the second bean, it falls within the transaction context; it propagates up and the container traps it in the first bean and rolls back the transaction. In case two the second bean doesn't participate in the transaction and the transaction context is not propagated to it. The exception thrown falls outside the transaction context; the container detects this and rolls back the transaction. There is no way, however, to undo any changes made in the second bean. In the third case the second bean has a new transaction context for each of the methods. The transaction for the exception-throwing method is rolled back, the exception moves up and the container rolls back the initial transaction. The other method executes successfully in its own transaction. In general, methods should be logically atomic all or nothing. If an exception is intended to indicate that the method can't complete successfully, it shouldn't be caught. If it is caught, the method should try to correct the problem and continue. The method must throw the exception and propagate out of the method for the transaction to be rolled back. Application exceptions won't cause a rollback if they're thrown and caught within the transactional scope. Runtime exceptions or unchecked exceptions, on the other hand, always cause a transaction to roll back, regardless of the transaction attribute or transactional scope.
Unilateral Decisions
Reader Feedback: Page 1 of 1
Latest Cloud Developer Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week
|
||||||||||||||||||||||||||||||||||||||||||||||||