11.2 Transactions in Java


Now that we have introduced the concept of a transaction and distributed transactions, let us now look at how transactions are supported and used in existing Java applications.

11.2.1 JDBC transactions

Java applications can include transactional constructs at different levels. An application interacting with a datastore using JDBC can use JDBC level transactions. A JDBC transaction is controlled by the transaction manager of the underlying datastore and is demarcated using the commit and rollback methods of the java.sql.Connection interface. For example:

 
 Connection conn =DriverManager.getConnection                          ("jdbc:oracle:thin:@jdo:Oracle"); conn.setAutoCommit(false); try{     Statement stmt = con.createStatement();     stmt.executeUpdate("  UPDATE USERS  SET username  ='corejdo'   WHERE ACCOUNTID=1829  ");     stmt.executeUpdate("  UPDATE ACCOUNTS set ACCOUNTTYPE=09   WHERE ACCOUNTID=1829  ");     conn.commit();    }catch(Exception e){             conn.rollback();      } 

JDBC transactions, although simple, are not suitable for controlling transactions that span multiple application components . The connection-based demarcation is local to the component in which it is used, and the transaction context is not propagated. For distributed environments such as J2EE, a different framework is needed that caters to transactional resources in general, not just databases. This is where JTA and JTS come in.

11.2.2 JTA and JTS

The Java Transaction API (JTA) and Java Transaction Service (JTS) provide the necessary and generic framework for applications to use transactions across multiple components and datastores.

The OMG Object Transaction Service (OTS) specifies how a transaction service can be implemented and the associated IDL interfaces. OTS is the transaction service used in CORBA to provide the transaction- related plumbing. JTS is the Java mapping of the IDL interfaces that defines how the service should be implemented in Java and the functionality that it must expose. Vendors (such as J2EE application server vendors ) use and provide the implementation of the JTS in their products; developers never work directly with JTS.

Java Transaction API (JTA) provides the API and the standard Java interface for developers to access the facilities of a transaction service (i.e., the JTS implementation). It provides an interface for the transaction manger, which manages the underlying transaction service. The following list summarizes (and Figure 11-3 illustrates) how JTA and JTS work together:

  • Transactional objects like EJBs and Java classes obtain a reference to the instance of the JTA UserTransaction interface and demarcate transactions.

  • Vendors provide the JTS implementation and a transaction manager implementation. This is exposed using the JTA TransactionManager interface.

  • When a transaction is begun by the transactional object, the transaction manager creates an instance of the transaction object, represented by the JTA Transaction interface, and associates it with the calling thread.

  • When the transactional object uses the transactional resource, the resource is enlisted with the transaction manager.

Figure 11-3. Different entities in JTA.

graphics/11fig03.jpg

Important Definitions

Enlistment refers to the process of making a resource a participant in a specific transaction and occurs in two flavors:

Static enlistment: The application server automatically enlists the resource in any transactions that it handles before any application code executes, e.g., at start-up.

Dynamic enlistment: Some container implementations are smart enough to realize that enlistment is not needed until the resource is used, and they enlist the resource dynamically when it is accessed.


The code below shows how the UserTransaction can be used in an application:

 
 UserTransaction  tx =// lookup user transaction object tx.begin();  // do some work across multiple components and datastores tx.rollback(); 

In the above code, the reference to the UserTransaction can be obtained from the JNDI context of the J2EE application or by using the EJB context if the component is an EJB. For example:

 
 Properties p= new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"some.vendor.factor.class"); p.put(Context.PROVIDER_URL, "applciation serve URL); InitialContext ic = new InitialContext(p); UserTransaction    tx = UserTransaction)ic.lookup("javax.transaction.UserTransaction"); //Or in EJB's UserTransaction    tx = ejbContext.getUserTransaction() ; 

The UserTransaction is simple and is used only to mark the transactional boundary. The application code never has access to the actual Transaction object. In this sense, the UserTransaction name is a misnomer because it works as more of a user transaction manager. It does not represent a single transaction, but the application's ability to begin and commit transactions. Table 11-1 lists some of the important methods in the UserTransaction interface.

Table 11-1. Methods in the UserTransaction

UserTransaction Method

Description

void begin()

Tells the transaction manager to create a new transaction and to associate it with the current thread.

void commit()

Commits and makes permanent the changes made in the transaction.

int getStatus()

Gets the status of the transaction associated with the current thread.

void rollback()

Rolls back and undoes the changes made in the transaction.

void setRollbackOnly()

When this is invoked, the transaction manager is informed that the only possible outcome of the transaction is to undo and roll back the work done in the transaction.

Void setTransactionTimeout (int seconds)

Sets the timeout value.

The interface javax.transaction.TransactionManager has methods identical to the UserTransaction with the additional ability to return the Transaction object. The TransactionManager also has two additional methods that allow the transaction to be suspended and resumed. These are listed in Table 11-2. J2EE does not mandate that a container expose the TransactionManager interface to application code (application code always works with UserTransaction ); therefore, some containers may not expose this. Typically, containers bind the TransactionManager to a specific JNDI name for their product.

Table 11-2. Additional Methods in the TransactionManager

TransactionManager Methods

Description

Transaction getTransaction()

Returns the actual Transaction object associated with the current thread.

Transaction suspend()

Suspends the current transaction.

void resume(Transaction tobj)

Resumes execution of the current transaction.

The javax.transaction.Transaction object is used by the TransactionManager as an abstraction to the actual executing transaction. Application code almost never accesses the actual Transaction object. It is here that the resource enlistment and de-enlistment takes place. Table 11-3 summarizes the methods in this interface.

Table 11-3. The Methods in the javax.transaction.Transaction interface

Transaction Methods

Description

boolean enlistResource XAResource xares)

Invoked by the TransactionManager to enlist the resource with the transaction.

boolean delistResource XAResource xares,int flag)

Invoked by the TransactionManager to delist the resource with the transaction.

void registerSynchronization (Synchronization sync)

An object implementing the javax.transaction.Synchronization interface can be registered with the Transaction to receive callbacks. The TransactionManager invokes the beforeCompletion() method in the passed object before starting the transaction commit process and the afterCompletion() method when the transaction has completed.

Now that you have an overall understanding of how transactions work and how they are abstracted by JTA and JTS for use in Java and J2EE, look at how JDO deals with transactions.



Core Java Data Objects
Core Java Data Objects
ISBN: 0131407317
EAN: 2147483647
Year: 2003
Pages: 146

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