Download PDF Home History |  | API Search Feedback FAQ

> ## Bean-Managed Transactions

> In a bean-managed transaction, the code in the session or message-driven bean explicitly marks the boundaries of the transaction. An entity bean cannot have bean-managed transactions; it must use container-managed transactions instead. Although beans with container-managed transactions require less coding, they have one limitation: When a method is executing, it can be associated with either a single transaction or no transaction at all. If this limitation will make coding your bean difficult, you should consider using bean-managed transactions.

> The following pseudocode illustrates the kind of fine-grained control you can obtain with bean-managed transactions. By checking various conditions, the pseudocode decides whether to start or stop different transactions within the business method.

>     begin transaction
>     ...
>     update table-a
>     ...
>     if (condition-x)
>        commit transaction
>     else if (condition-y)
>        update table-b
>        commit transaction
>     else
>        rollback transaction
>        begin transaction
>        update table-c
>        commit transaction

> When coding a bean-managed transaction for session or message-driven beans, you must decide whether to use JDBC or JTA transactions. The sections that follow discuss both types of transactions.

> ### JDBC Transactions

> A JDBC transaction is controlled by the transaction manager of the DBMS. You may want to use JDBC transactions when wrapping legacy code inside a session bean. To code a JDBC transaction, you invoke the `commit` and `rollback` methods of the `java.sql.Connection` interface. The beginning of a transaction is implicit. A transaction begins with the first SQL statement that follows the most recent `commit`, `rollback`, or `connect` statement. (This rule is generally true but may vary with DBMS vendor.)

> The source code for the following example is in the `<``INSTALL``>/j2eetutorial14/examples/ejb/warehouse/` directory.

> The following code is from the `WarehouseBean` example, a session bean that uses the `Connection` interface's methods to delimit bean-managed transactions. The `ship` method starts by invoking `setAutoCommit` on the `Connection` object named `con`. This invocation tells the DBMS not to automatically commit every SQL statement. Next, the `ship` method calls routines that update the `order_item` and `inventory` database tables. If the updates succeed, the transaction is committed. If an exception is thrown, however, the transaction is rolled back.

>     public void ship (String productId, String orderId, int
>     quantity) {

>        try {
>           makeConnection();
>           con.setAutoCommit(false);
>           updateOrderItem(productId, orderId);
>           updateInventory(productId, quantity);
>           con.commit();
>        } catch (Exception ex) {
>            try {
>               con.rollback();
>               throw new EJBException("Transaction failed: " +
>                  ex.getMessage());
>            } catch (SQLException sqx) {
>                throw new EJBException("Rollback failed: " +
>                   sqx.getMessage());
>            }
>         } finally {
>             releaseConnection();
>         }
>     }

> ### Deploying and Running the WarehouseBean Example

> `WarehouseBean` is a session bean that uses bean-managed, JDBC transactions. These steps assume that you are familiar with the steps needed to create and deploy an enterprise application using `deploytool`, as described in Chapter 25. To deploy and run the example, do the following.

> ### Compiling the WarehouseBean Example

> To compile the classes and interfaces in the `WarehouseBean` example, follow these steps:

> 1. In a terminal window, go to this directory:

> `<``INSTALL``>/j2eetutorial14/examples/ejb/warehouse/`

> 2. Start the PointBase server. For instructions, see Starting and Stopping the PointBase Database Server.
> 3. Create the database tables and data by typing

> `asant create-db_common`

> 4. Type the following command to build the enterprise bean's classes and interfaces:

> `asant build`

> ### Packaging the WarehouseBean Example

> The `WarehouseBean` session bean uses bean-managed transactions. These steps assume that you are familiar with the steps needed to create and deploy an enterprise application using `deploytool`, as described in Chapter 24.

> #### Creating the J2EE Application

> Create a new application named `WarehouseApp` in:

>     <INSTALL>/j2eetutorial14/examples/ejb/warehouse/

> #### Packaging the Enterprise Bean

> 1. Create a new enterprise bean in `WarehouseApp` by selecting FileNew Enterprise Bean.
> 2. In the EJB JAR screen:
> 1. Select Create New JAR Module in Application.
> 2. Enter `WarehouseJAR` under JAR Name.
> 3. Click Edit.
> 4. Navigate to `<``INSTALL``>/j2eetutorial14/examples/ejb/warehouse/`.
> 5. Select `Warehouse.class`, `WarehouseBean.class`, and `WarehouseHome.class`.
> 6. Click Add.
> 7. Click OK.
> 8. Click Next.
> 3. In the General screen:
> 1. Select `WarehouseBean` under Enterprise Bean Class.
> 2. Enter `WarehouseBean` under Enterprise Bean Name.
> 3. Select Stateful Session under Enterprise Bean Type.
> 4. Select `WarehouseHome` under Remote Home Interface.
> 5. Select `Warehouse` under Remote Interface.
> 6. Select Next.
> 4. Click Finish.
> 5. Select `WarehouseBean` in `deploytool`'s tree.
> 6. In the Transactions tab select Bean-Managed under Transaction Management.
> 7. In the Resource Ref's tab:
> 1. Click Add.
> 2. Double-click the Coded Name column for the row that was just created.
> 3. Enter `jdbc/WarehouseDB`.
> 4. Under Sun-specific Settings for `jdbc/WarehouseDB` in the JNDI Name field, select `jdbc/ejbTutorialDB`.

> #### Packaging the Application Client

> 1. Create a new application client in `WarehouseApp` by selecting FileNewApplication Client.
> 2. In the JAR File Contents screen:
> 1. Select `WarehouseApp` under Create New AppClient Module in Application.
> 2. Enter `WarehouseClient` under AppClient Name.
> 3. Click Edit.
> 4. Navigate to `<``INSTALL``>/j2eetutorial14/examples/ejb/warehouse/`.
> 5. Select `WarehouseClient.class`.
> 6. Click Add.
> 7. Click OK.
> 8. Click Next.
> 3. In the General screen:
> 1. Select `WarehouseClient` under Main Class.
> 2. Select `(Use container-managed authentication)` under Callback Handler Class.
> 3. Click Next.
> 4. Click Finish.

> #### Specifying the Application Client's Enterprise Bean Reference

> When it invokes the `lookup` method, `WarehouseClient` refers to the home of an enterprise bean:

>     Object objref =
>     initial.lookup("java:comp/env/ejb/SimpleWarehouse");

> You specify this reference as follows:

> 1. In the tree, select `WarehouseClient`.
> 2. Select the EJB Ref's tab.
> 3. Click Add.
> 4. In the Coded Name field, enter `ejb/SimpleWarehouse`.
> 5. In the EJB Type field, select `Session`.
> 6. In the Interfaces field, select `Remote`.
> 7. In the Home Interface field, enter `WarehouseHome`.
> 8. In the Local/Remote Interface field, enter `Warehouse`.
> 9. Click OK.
> 10. Select the line you just added.
> 11. Under Sun-specific Settings for `ejb/SimpleWarehouse`, select JNDI Name.
> 12. In the JNDI Name field, select `WarehouseBean`.
> 13. Select FileSave.

> #### Deploying the J2EE Application

> 1. Select `WarehouseApp` in `deploytool`.
> 2. Select ToolsDeploy.
> 3. Under Connection Settings, enter the user name and password for the Application Server.
> 4. Tell `deploytool` to create a JAR file that contains the client stubs:
> 1. Check the Return Client JAR box.
> 2. In the field below the checkbox, enter `<``INSTALL``>/j2eetutorial14/examples/ejb/warehouse/`.
> 5. Click OK.
> 6. In the Distribute Module dialog box, click Close when the deployment completes successfully.

> #### Running the Application Client

> 1. In a terminal window, go to the `<INSTALL>``/j2eetutorial14/
>    examples/ejb/warehouse/` directory.
> 2. Type the following command:

> `appclient -client WarehouseAppClient.jar`

> In the terminal window, the client displays these lines:

>     status = shipped

> ### JTA Transactions

> JTA is the abbreviation for the Java Transaction API. This API allows you to demarcate transactions in a manner that is independent of the transaction manager implementation. The Application Server implements the transaction manager with the Java Transaction Service (JTS). But your code doesn't call the JTS methods directly. Instead, it invokes the JTA methods, which then call the lower-level JTS routines.

> A JTA transaction is controlled by the J2EE transaction manager. You may want to use a JTA transaction because it can span updates to multiple databases from different vendors. A particular DBMS's transaction manager may not work with heterogeneous databases. However, the J2EE transaction manager does have one limitation: it does not support nested transactions. In other words, it cannot start a transaction for an instance until the preceding transaction has ended.

> The source code for the following example is in the `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/` directory.

> To demarcate a JTA transaction, you invoke the `begin`, `commit`, and `rollback` methods of the `javax.transaction.UserTransaction` interface. The following code, taken from the `TellerBean` class, demonstrates the `UserTransaction` methods. The `begin` and `commit` invocations delimit the updates to the database. If the updates fail, the code invokes the `rollback` method and throws an `EJBException`.

>     public void withdrawCash(double amount) {

>        UserTransaction ut = context.getUserTransaction();

>        try {
>           ut.begin();
>           updateChecking(amount);
>           machineBalance -= amount;
>           insertMachine(machineBalance);
>           ut.commit();
>        } catch (Exception ex) {
>            try {
>               ut.rollback();
>            } catch (SystemException syex) {
>                throw new EJBException
>                   ("Rollback failed: " + syex.getMessage());
>            }
>            throw new EJBException
>               ("Transaction failed: " + ex.getMessage());
>         }
>     }

> ### Deploying and Running the TellerBean Example

> The `TellerBean` session bean uses bean-managed JTA transactions. These steps assume that you are familiar with the steps needed to create and deploy an enterprise application using `deploytool`, as described in Chapter 25. To deploy and run the `TellerBean` example, perform these steps.

> ### Compiling the TellerBean Example

> To compile the classes and interfaces in the `TellerBean` example, follow these steps:

> 1. In a terminal window, go to this directory:

> `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/`

> 2. Start the PointBase server. For instructions, see Starting and Stopping the PointBase Database Server.
> 3. Create the database tables and data by typing

> `asant create-db_common`

> 4. Type the following command to build the enterprise bean's classes and interfaces:

> `asant build`

> ### Packaging the TellerBean Example

> The `TellerBean` session bean uses JTA transactions. These steps assume that you are familiar with the steps needed to create and deploy an enterprise application using `deploytool`, as described in Chapter 24.

> #### Creating the J2EE Application

> Create a new application named `TellerApp` in

> `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/`

> #### Packaging the Enterprise Bean

> 1. Create a new enterprise bean in `TellerApp` by selecting FileNew Enterprise Bean.
> 2. In the EJB JAR screen:
> 1. Select Create New JAR Module in Application.
> 2. Enter `TellerJAR` under JAR Name.
> 3. Click Edit.
> 4. Navigate to `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/`.
> 5. Select `Teller.class`, `TellerBean.class`, and `TellerHome.class`.
> 6. Click Add.
> 7. Click OK.
> 8. Click Next.
> 3. In the General screen:
> 1. Select `TellerBean` under Enterprise Bean Class.
> 2. Enter `TellerBean` under Enterprise Bean Name.
> 3. Select Stateful Session under Enterprise Bean Type.
> 4. Select `TellerHome` under Remote Home Interface.
> 5. Select `Teller` under Remote Interface.
> 6. Select Next.
> 4. Click Finish.
> 5. Select `TellerBean` in `deploytool`'s tree.
> 6. In the Transactions tab select Bean-Managed under Transaction Management.
> 7. In the Resource Ref's tab:
> 1. Click Add.
> 2. Double-click the Coded Name column for the row that was just created.
> 3. Enter `jdbc/TellerDB`.
> 4. Under Sun-specific Settings for `jdbc/TellerDB` in the JNDI Name field, select `jdbc/ejbTutorialDB`.

> #### Packaging the Application Client

> 1. Create a new application client in `TellerApp` by selecting FileNewApplication Client.
> 2. In the JAR File Contents screen:
> 1. Select `TellerApp` under Create New AppClient Module in Application.
> 2. Enter `TellerClient` under AppClient Name.
> 3. Click Edit.
> 4. Navigate to `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/`.
> 5. Select `TellerClient.class`.
> 6. Click Add.
> 7. Click OK.
> 8. Click Next.
> 3. In the General screen:
> 1. Select `TellerClient` under Main Class.
> 2. Select `(Use container-managed authentication)` under Callback Handler Class.
> 3. Click Next.
> 4. Click Finish.

> #### Specifying the Application Client's Enterprise Bean Reference

> When it invokes the `lookup` method, `TellerClient` refers to the home of an enterprise bean:

>     Object objref =
>     initial.lookup("java:comp/env/ejb/SimpleTeller");

> You specify this reference as follows:

> 1. In the tree, select `TellerClient`.
> 2. Select the EJB Ref's tab.
> 3. Click Add.
> 4. In the Coded Name field, enter `ejb/SimpleTeller`.
> 5. In the EJB Type field, select `Session`.
> 6. In the Interfaces field, select `Remote`.
> 7. In the Home Interface field, enter `TellerHome`.
> 8. In the Local/Remote Interface field, enter `Teller`.
> 9. Click OK.
> 10. Select the line you just added.
> 11. Under Sun-specific Settings for `ejb/SimpleTeller`, select JNDI Name.
> 12. In the JNDI Name field, select `TellerBean`.
> 13. Select FileSave.

> #### Deploying the J2EE Application

> 1. Select `TellerApp` in `deploytool`.
> 2. Select ToolsDeploy.
> 3. Under Connection Settings, enter the user name and password for the Application Server.
> 4. Tell `deploytool` to create a JAR file that contains the client stubs:
> 1. Check the Return Client JAR box.
> 2. In the field below the checkbox, enter `<``INSTALL``>/j2eetutorial14/examples/ejb/teller/`.
> 5. Click OK.
> 6. In the Distribute Module dialog box, click Close when the deployment completes successfully.

> #### Running the Application Client

> 1. In a terminal window, go to the `<INSTALL>``/j2eetutorial14/
>    examples/ejb/teller/` directory.
> 2. Type the following command:

> `appclient -client TellerAppClient.jar`

> In the terminal window, the client displays these lines:

>     checking = 500.0
>     checking = 440.0

> ### Returning without Committing

> In a stateless session bean with bean-managed transactions, a business method must commit or roll back a transaction before returning. However, a stateful session bean does not have this restriction.

> In a stateful session bean with a JTA transaction, the association between the bean instance and the transaction is retained across multiple client calls. Even if each business method called by the client opens and closes the database connection, the association is retained until the instance completes the transaction.

> In a stateful session bean with a JDBC transaction, the JDBC connection retains the association between the bean instance and the transaction across multiple calls. If the connection is closed, the association is not retained.

> ### Methods Not Allowed in Bean-Managed Transactions

> Do not invoke the `getRollbackOnly` and `setRollbackOnly` methods of the `EJBContext` interface in bean-managed transactions. These methods should be used only in container-managed transactions. For bean-managed transactions, invoke the `getStatus` and `rollback` methods of the `UserTransaction` interface.

Download PDF Home History |  | API Search Feedback FAQ

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.