EJB.11.3 Bean Provider s Responsibilities


EJB.11.3 Bean Provider's Responsibilities

This section describes the bean provider's view of transactions and defines his responsibilities.

EJB.11.3.1 Bean-Managed Versus Container-Managed Transaction Demarcation

When designing an enterprise bean, the bean provider must decide whether the enterprise bean will demarcate transactions programmatically in the business methods (bean-managed transaction demarcation), or whether the transaction demarcation is to be performed by the container based on the transaction attributes in the deployment descriptor (container-managed transaction demarcation).

A session bean can be designed with bean-managed transaction demarcation or with container-managed transaction demarcation. (But it cannot be both at the same time.)

An entity bean must always be designed with container-managed transaction demarcation.

An enterprise bean instance can access resource managers in a transaction only in the enterprise bean's methods in which there is a transaction context available. Refer to Table EJB.6-1 on page 406, Table EJB.6-2 on page 417, and Table EJB.9-1 on page 459.

EJB.11.3.1.1 Non-Transactional Execution

Some enterprise beans may need to access resource managers that do not support an external transaction coordinator. The container cannot manage the transactions for such enterprise beans in the same way that it can for the enterprise beans that access resource managers that support an external transaction coordinator .

If an enterprise bean needs to access a resource manager that does not support an external transaction coordinator, the bean provider should design the enterprise bean with container-managed transaction demarcation and assign the NotSupported transaction attribute to all the bean's methods. The EJB architecture does not specify the transactional semantics of the enterprise bean methods. See Section EJB.11.6.3 for how the container implements this case.

EJB.11.3.2 Isolation Levels

Transactions not only make completion of a unit of work atomic, they also isolate the units of work from each other, provided that the system allows concurrent execution of multiple units of work.

The isolation level describes the degree to which the access to a resource manager by a transaction is isolated from the access to the resource manager by other concurrently executing transactions.

The following are guidelines for managing isolation levels in enterprise beans.

  • The API for managing an isolation level is resource-manager specific. (Therefore, the EJB architecture does not define an API for managing isolation level.)

  • If an enterprise bean uses multiple resource managers, the bean provider may specify the same or different isolation level for each resource manager. This means, for example, that if an enterprise bean accesses multiple resource managers in a transaction, access to each resource manager may be associated with a different isolation level.

  • The bean provider must take care when setting an isolation level. Most resource managers require that all accesses to the resource manager within a transaction are done with the same isolation levels. An attempt to change the isolation level in the middle of a transaction may cause undesirable behavior, such as an implicit sync point (a commit of the changes done so far).

  • For session beans with bean-managed transaction demarcation, the bean provider can specify the desirable isolation level programmatically in the enterprise bean's methods, using the resource-manager specific API. For example, the bean provider can use the java.sql.Connection.setTransactionIsolation(...) method to set the appropriate isolation level for database access.

  • For entity beans using container-managed persistence, transaction isolation is managed by the data access classes that are generated by the container provider's tools. The tools must ensure that the management of the isolation levels performed by the data access classes will not result in conflicting isolation level requests for a resource manager within a transaction.

  • Additional care must be taken if multiple enterprise beans access the same resource manager in the same transaction. Conflicts in the requested isolation levels must be avoided.

EJB.11.3.3 Enterprise Beans Using Bean-Managed Transaction Demarcation

This subsection describes the requirements for the bean provider of an enterprise bean with bean-managed transaction demarcation.

The enterprise bean with bean-managed transaction demarcation must be a session bean.

An instance that starts a transaction must complete the transaction before it starts a new transaction.

The bean provider uses the UserTransaction interface to demarcate transactions. All updates to the resource managers between the UserTransaction.begin() and UserTransaction.commit () methods are performed in a transaction. While an instance is in a transaction, the instance must not attempt to use the resource-manager specific transaction demarcation API (e.g., it must not invoke the commit() or rollback() method on the java.sql.Connection interface).

A stateful session bean instance may, but is not required to, commit a started transaction before a business method returns. If a transaction has not been completed by the end of a business method, the container retains the association between the transaction and the instance across multiple client calls until the instance eventually completes the transaction.

The bean-managed transaction demarcation programming model presented to the programmer of a stateful session bean is natural because it is the same as that used by a stand-alone Java application.

A stateless session bean instance must commit a transaction before a business method returns.

The following example illustrates a business method that performs a transaction involving two database connections.

 public class MySessionEJB implements SessionBean {    EJBContext ejbContext;     public void someMethod(...) {       javax.transaction.UserTransaction ut;        javax.sql.DataSource ds1;        javax.sql.DataSource ds2;        java.sql.Connection con1;        java.sql.Connection con2;        java.sql.Statement stmt1;        java.sql.Statement stmt2;        InitialContext initCtx = new InitialContext();        // obtain con1 object and set it up for transactions        ds1 = (javax.sql.DataSource)               initCtx.lookup("java:comp/env/jdbcDatabase1");        con1 = ds1.getConnection();        stmt1 = con1.createStatement();        // obtain con2 object and set it up for transactions        ds2 = (javax.sql.DataSource)               initCtx.lookup("java:comp/env/jdbcDatabase2");        con2 = ds2.getConnection();        stmt2 = con2.createStatement();        //        // Now do a transaction that involves con1 and con2.        //        ut = ejbContext.getUserTransaction();        // start the transaction        ut.begin();        // Do some updates to both con1 and con2. The Container        // automatically enlists con1 and con2 with the transaction.        stmt1.executeQuery(...);        stmt1.executeUpdate(...);        stmt2.executeQuery(...);        stmt2.executeUpdate(...);        stmt1.executeUpdate(...);        stmt2.executeUpdate(...);        // commit the transaction        ut.commit();        // release connections        stmt1.close();        stmt2.close();        con1.close();        con2.close();     }     ...  } 

The following example illustrates a stateful session bean that retains a transaction across three client calls, invoked in the following order: method1 , method2 , and method3 .

 public class MySessionEJB implements SessionBean {    EJBContext ejbContext;     javax.sql.DataSource ds1;     javax.sql.DataSource ds2;     java.sql.Connection con1;     java.sql.Connection con2;     public void method1(...) {       java.sql.Statement stmt;        InitialContext initCtx = new InitialContext();        // obtain user transaction interface        ut = ejbContext.getUserTransaction();        // start a transaction        ut.begin();        // make some updates on con1        ds1 = (javax.sql.DataSource)               initCtx.lookup("java:comp/env/jdbcDatabase1");        con1 = ds1.getConnection();        stmt = con1.createStatement();        stmt.executeUpdate(...);        stmt.executeUpdate(...);        //        // The container retains the transaction associated with the        // instance to the next client call (which is method2(...)).     }     public void method2(...) {       java.sql.Statement stmt;        InitialContext initCtx = new InitialContext();        // make some updates on con2        ds2 = (javax.sql.DataSource)               initCtx.lookup("java:comp/env/jdbcDatabase2");        con2 = ds2.getConnection();        stmt = con2.createStatement();        stmt.executeUpdate(...);        stmt.executeUpdate(...);        // The container retains the transaction associated with the        // instance to the next client call (which is method3(...)).     }     public void method3(...) {       java.sql.Statement stmt;        // obtain user transaction interface        ut = ejbContext.getUserTransaction();        // make some more updates on con1 and con2        stmt = con1.createStatement();        stmt.executeUpdate(...);        stmt = con2.createStatement();        stmt.executeUpdate(...);        // commit the transaction        ut.commit();        // release connections        stmt.close();        con1.close();        con2.close();     }     ...  } 

It is possible for an enterprise bean to open and close a database connection in each business method (rather than hold the connection open until the end of transaction). In the following example, if the client executes the sequence of methods ( method1 , method2 , method2 , method2 , and method3 ) , all the database updates done by the multiple invocations of method2 are performed in the scope of the same transaction, which is the transaction started in method1 and committed in method3 .

 public class MySessionEJB implements SessionBean {    EJBContext ejbContext;     InitialContext initCtx;     public void method1(...) {       java.sql.Statement stmt;        // obtain user transaction interface        ut = ejbContext.getUserTransaction();        // start a transaction        ut.begin();     }     public void method2(...) {       javax.sql.DataSource ds;        java.sql.Connection con;        java.sql.Statement stmt;        // open connection        ds = (javax.sql.DataSource)              initCtx.lookup("java:comp/env/jdbcDatabase");        con = ds.getConnection();        // make some updates on con        stmt = con.createStatement();        stmt.executeUpdate(...);        stmt.executeUpdate(...);        // close the connection        stmt.close();        con.close();     }     public void method3(...) {       // obtain user transaction interface        ut = ejbContext.getUserTransaction();        // commit the transaction        ut.commit();     }     ...  } 
EJB.11.3.3.1 getRollbackOnly() and setRollbackOnly() Methods

An enterprise bean with bean-managed transaction demarcation must not use the getRollbackOnly() and setRollbackOnly() methods of the EJBContext interface.

An enterprise bean with bean-managed transaction demarcation has no need to use these methods, because of the following reasons:

  • An enterprise bean with bean-managed transaction demarcation can obtain the status of a transaction by using the getStatus() method of the javax.transaction.UserTransaction interface.

  • An enterprise bean with bean-managed transaction demarcation can roll back a transaction using the rollback() method of the javax.transaction.UserTrasaction interface.

EJB.11.3.4 Enterprise Beans Using Container-Managed Transaction Demarcation

This subsection describes the requirements for the bean provider of an enterprise bean using container-managed transaction demarcation.

The enterprise bean's business methods must not use any resource-manager specific transaction management methods that would interfere with the container's demarcation of transaction boundaries. For example, the enterprise bean methods must not use the following methods of the java.sql.Connection interface: commit() , setAutoCommit(...) , and rollback() .

The enterprise bean's business methods must not attempt to obtain or use the javax.transaction.UserTransaction interface.

The following is an example of a business method in an enterprise bean with container-managed transaction demarcation. The business method updates two databases using JDBC API connections. The container provides transaction demarcation per the application assembler's instructions.

 public class MySessionEJB implements SessionBean {    EJBContext ejbContext;     public void someMethod(...) {       java.sql.Connection con1;        java.sql.Connection con2;        java.sql.Statement stmt1;        java.sql.Statement stmt2;        // obtain con1 and con2 connection objects        con1 = ...;        con2 = ...;        stmt1 = con1.createStatement();        stmt2 = con2.createStatement();        //        // Perform some updates on con1 and con2. The container        // automatically enlists con1 and con2 with the container-       // managed transaction.        //        stmt1.executeQuery(...);        stmt1.executeUpdate(...);        stmt2.executeQuery(...);        stmt2.executeUpdate(...);        stmt1.executeUpdate(...);        stmt2.executeUpdate(...);        // release connections        con1.close();        con2.close();     }     ...  } 
EJB.11.3.4.1 javax.ejb.SessionSynchronization Interface

A stateful session bean with container-managed transaction demarcation can optionally implement the javax.ejb.SessionSynchronization interface. The use of the SessionSynchronization interface is described in Section EJB.6.5.2.

EJB.11.3.4.2 javax.ejb.EJBContext.setRollbackOnly() Method

An enterprise bean with container-managed transaction demarcation can use the setRollbackOnly() method of its EJBContext object to mark the transaction such that the transaction can never commit. Typically, an enterprise bean marks a transaction for rollback to protect data integrity before throwing an application exception, because application exceptions do not automatically cause the container to roll back the transaction.

For example, an AccountTransfer bean which debits one account and credits another account could mark a transaction for rollback if it successfully performs the debit operation, but encounters a failure during the credit operation.

EJB.11.3.4.3 javax.ejb.EJBContext.getRollbackOnly() Method

An enterprise bean with container-managed transaction demarcation can use the getRollbackOnly() method of its EJBContext object to test if the current transaction has been marked for rollback. The transaction might have been marked for rollback by the enterprise bean itself, by other enterprise beans, or by other components (outside the EJB specification scope) of the transaction processing infrastructure.

EJB.11.3.5 Declaration in Deployment Descriptor

The bean provider of a session bean must use the transaction-type element to declare whether the session bean is of the bean-managed or container-managed transaction demarcation type. (See Chapter EJB.16 for information about the deployment descriptor.)

The transaction-type element is not supported for entity beans because all entity beans must use container-managed transaction demarcation.

The bean provider of an enterprise bean with container-managed transaction demarcation may optionally specify the transaction attributes for the enterprise bean's methods. See Section EJB.11.4.1.



Java 2 Platform, Enterprise Edition. Platform and Component Specifications
Java 2 Platform, Enterprise Edition: Platform and Component Specifications
ISBN: 0201704560
EAN: 2147483647
Year: 2000
Pages: 399

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