Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Transactions in the Geronimo application server

Neal Sanche (neal@nsdev.org), Java Developer, Pure Technologies
Author photo
Neal Sanche is a Java developer recently beached in the Microsoft® .NET world and fighting for any ties back to his old, comfortable roots. His experience includes development of several commercial J2EE applications, as well as several stand-alone Java applications. In his spare time, he writes music, takes photographs, and writes technical articles. Visit his Web site to see several examples of each.

Summary:  Transactions are a necessary part of any Java™ 2 Platform, Enterprise Edition (J2EE) application, and you use them often when you access databases. In fact, transactions are critical to maintaining data integrity in case of unforeseen failures. Java developer and regular contributor Neal Sanche describes the essentials of J2EE transactions and how they're used within the Apache Geronimo application server. To demonstrate transactions, you'll use Transaction Demo, a sample program with a simple menu that allows you to interact with a database of star names.

Date:  11 Oct 2005
Level:  Intermediate
Also available in:   Japanese

Activity:  5349 views
Comments:  

Transactions overview

When writing almost any application for Geronimo, you encounter the need to create and handle transactions. In many circumstances, such as manipulating database records, operating on container-managed relations (CMRs), and sending Java Message Service (JMS) messages, Geronimo forces you to use transactions, or else it returns with an error condition.

Transactions defined


A transaction is an atomic set of actions that can be revoked if there is an error. If any of the actions fails, none of the actions is taken.

A container-managed relation (CMR) is a J2EE concept that provides automatic persistence of a set of entities and the relations between them. For example, an order record might have many line items. This would be handled automatically by the Geronimo container so that all the SQL statements are performed behind the scenes.

A container-managed transaction (CMT) is a transaction that is provided automatically by the Geronimo container, is managed by the container, and doesn't need code written to handle it.

With container-managed persistence (CMP), the Enterprise JavaBeans (EJB) container automatically manages the persistent state. CMP requires less code while providing better performance.

To get more familiar with the important details of using transactions in Geronimo applications, you'll work with a small application called Transaction Demo, created for deployment in a Geronimo application server. The development was based on an early release of Geronimo M5 (the fifth milestone release). (See Resources for a link to the Apache Software Foundation site to download the latest release of the Geronimo application server.)

J2EE applications use transactions whenever databases are accessed during CMP. If an error occurs while creating, updating, or deleting an entity bean, the previous state of the database can be restored, and the user can be notified that there was a problem. The main concern here is data integrity. A transaction protects data integrity in your database by undoing any potentially incomplete operations.

In a J2EE application you can either create a transaction and manage its lifetime in your own code by obtaining and using instances of the UserTransaction class (see the Directly remove Sol section), or you can rely on the EJB container to create and manage transactions for you by employing CMTs. You get details about using both of these methods with the Geronimo application server.

As previously mentioned, transactions aren't just for databases. A key part of the J2EE specification describes the use of transactions within the Java Message Service (JMS). JMS is a critical component of message-driven beans (MDBs) and can be used within a transaction so that messages that could not be delivered due to some exception will roll back the transaction, causing the message to be redelivered. Geronimo embeds the ActiveMQ JMS service, so you're welcome to try creating an MDB. You can even use the Geronimo console to start the SystemJMS configuration and configure the JMS server. This is beyond the scope of this article, however. (See Resources for more information on these topics.)

This article covers the use of transactions from within a Web application as well as through a stateless session bean instance using CMTs. It also shows examples of recovering from a failed transaction gracefully.


The sample program

Transaction Demo, the sample program used in this article to demonstrate transactions, is a Struts application that has all the deployment plans necessary to be deployed in the Geronimo application server. It provides a simple menu that allows you to interact with a basic database of stars (as in the sun and other celestial bodies, not Hollywood movie stars), and it demonstrates many key concepts of using transactions within your Geronimo programs.

To run the Transaction Demo program, you must first build the Geronimo application server from source code. The Maven build scripts for the sample program only complete if many of the Geronimo build products are available during build time. You also need to download XDoclet 1.2.3 from sourceforge.net (see Resources for a link) and install any missing binaries into your Maven repository. (This step won't be required when the IBiblio Maven repository includes all of the XDoclet 1.2.3 binaries. At the time of this writing, at least one binary is missing from the repository.)

After you have the build working correctly, you'll find in the resulting target directory a transactiondemo-ejb.sql file. This is the SQL schema for the application. If you complete the following steps, you can install the schema into the Apache Derby built-in database within Geronimo.

First, start up your Geronimo server with the following command line:

java -jar server.jar

This starts the server and the new Geronimo console, which manages your server and a list of other Geronimo services for deployment of applications. (Note: This is only true if you are using the M5 version of Geronimo. Previous versions only start a minimal server, and deploying to that would require you to start more services.)

Next, connect to the console with your Web browser by going to http://localhost:8080/console. You should see the console welcome screen, as shown in Figure 1. Log in with the default user name system and the password manager.


Figure 1. Geronimo console welcome screen
Geronimo console welcome screen

When you're logged in, navigate using the left navigation bar, and choose All Configurations. Look at the Installed Applications list, and ensure that you start (or see that it's running) the org/apache/geronimo/SystemDatabase configuration by clicking the Start link next to it. This starts the Apache Derby database engine so that you can configure it (see Figure 2). At a minimum, to compile and get the demo application running, you need to have at least the following configurations started:

org/apache/geronimo/RuntimeDeployer
org/apache/geronimo/JettyRuntimeDeployer
org/apache/geronimo/SystemDatabase


Figure 2. All Configurations with system database started
All Configurations with system database started

Next, scroll down to the bottom of the navigation bar, and select the DB Manager link. This portlet (as they are called by the console developers) provides a simple way to perform SQL queries against the system database and create new databases. Enter the SQL from the transactiondemo-ejb.sql file (without the drop table statement) into the SQL Command text area, and click the Run SQL button, as shown in Figure 3.


Figure 3. Installing the application database schema using the DB Manager
Installing the application database schema using the DB Manager

This creates the table needed by the demo application. You can see the tables in the database by clicking the Application link under the View Tables selection in the Database List section of the DB Manager portlet. Of course, exploring any of the other great features of the Geronimo console at this time is recommended. Now, if you've run the Maven command in the source directory, the transactiondemo application will be installed. You can access it by going to the URL http://localhost:8080/trasactiondemo where you can see the screen shown in Figure 4.


Figure 4. Transaction Demo application screen
Transaction Demo application screen

The menu links on the left side of the screen call database code with transactions in various ways. The meaning of these menu items is described below, but more precise details about each menu item's function are in subsections later in the article.

  • Clear clears the Stars database table.
  • Add Records with Failure adds several records, but the method throws an exception before finishing, so the CMT is rolled back automatically.
  • Add Records adds records without throwing an exception.
  • Directly Remove Sol demonstrates handling a transaction in the Web tier by obtaining a UserTransaction instance and using it within the Struts action.

The code for each of these options is described later in the article.

Clear the database

Selecting the Clear menu item clears the database records so you can start fresh when playing with the demo. To clear the database, the program uses a stateless session bean that automatically starts CMTs. The TransactionDemoSessionBean.java class contains a clear() method (see Listing 1) that performs the required iteration of the entities and removes each one. Because this is performed as a single transaction, the operation should be relatively fast, even though at a low level this is probably translated into one delete statement (in SQL) for each star.remove().


Listing 1. TransactionDemoSessionBean.java clear() method
        
/**
 * Perform the first test.
 * @throws NamingException 
 * @throws CreateException 
 * 
 * @ejb.interface-method view-type="both"
 * @ejb.transaction      type="Required"
 */
public void clear() {
   try {
      Collection stars = StarUtil.getLocalHome().findAll();
      Iterator i = stars.iterator();
      while(i.hasNext()) {
         StarLocal star = (StarLocal)i.next();
         star.remove();
      }
   } catch (Throwable ex) {
      ex.printStackTrace();
   }
}

This code is decorated with XDoclet tags, specifically the @ejb.transaction tag, which specifies that a transaction is required for entry into the clear() method. The XDoclet tag translates into an entry in the ejb-jar.xml deployment descriptor (see Listing 2) that instructs Geronimo to create a CMT if the calling thread is not already associated with a transaction.


Listing 2. ejb-jar.xml fragment for the clear() method
        
   <container-transaction>
      <method>
         <ejb-name>TransactionDemoSession</ejb-name>
         <method-intf>Local</method-intf>
         <method-name>clear</method-name>
         <method-params>
         </method-params>
      </method>
      <trans-attribute>Required</trans-attribute>
   </container-transaction>

The nice thing about CMTs is that you don't have to worry about starting them, rolling them back, or committing them. The container does all of that automatically. For example, if some sort of exception happened in the middle of removing all the star records from the database, Geronimo would initiate a rollback of the transaction, and none of the deletions would be committed within the clear() method. The following section demonstrates this rollback behavior.

Add Records with Failure

The Add Records with Failure menu item in the Transaction Demo application demonstrates what happens to a transaction when an exception occurs sometime during the operation. As mentioned in the previous section, if an exception occurs during a method that has been marked as having CMTs, the transaction will automatically be rolled back. In the code in Listing 3, there's an exception that is always thrown at the end of the method, thereby forcing a rollback.


Listing 3. test1() method, forced exception demonstrating rollback
        
 /**
  * Perform the first test. This test makes an attempt to 
  * add a number of stars, but then throws an exception.
  *
  * @throws NamingException 
  * @throws CreateException 
  * @throws IllegalStateException always
  * 
  * @ejb.interface-method view-type="both"
  * @ejb.transaction      type="Required"
  */
 public void test1() throws CreateException, NamingException, 
     IllegalStateException {
   StarLocalHome home = StarUtil.getLocalHome();
   home.create("Sol");
   home.create("Betelguese");
   home.create("Andromeda");
   throw new 
        IllegalStateException("Pretending that something"+
        " bad happened.");
   }

At the end of the method is an IllegalStateException that is always thrown. If the transactions work, you should never observe any of the stars -- Sol, Betelguese, or Andromeda -- being created within the database, because the exception rolls back any changes. As you can see, this is indeed what happens.

Add Records

The Add Records menu item in the Transaction Demo application does the opposite of the Add Records with Failure item. It demonstrates what happens if there are no exceptional circumstances; namely, it inserts records into the database. There isn't much going on in the method in Listing 4 except the fact that no exception is thrown by the code. So if all is well with the database, the CMT commits, and the records should appear in the list. Figure 5 shows the result of this operation in the test application. There is a way to produce an exception with this menu option, however. Simply running it twice will produce an error, because the same star names (which are the primary key for the table) are used again, causing an error with duplicate primary key values. If you use the fourth menu option to delete the star Sol, and then try creating the records again, Sol doesn't reappear because of this exception. The transaction is rolled back in that case.


Listing 4. test2() code, adding stars to the database
        
/**
 * Perform the second test. This test adds the stars, 
 * and if nothing goes wrong, they will be in the database.
 * @throws NamingException 
 * @throws CreateException 
 * 
 * @ejb.interface-method view-type="both"
 * @ejb.transaction      type="Required"
 */
public void test2() throws NamingException, CreateException {
   StarLocalHome home = StarUtil.getLocalHome();
   home.create("Sol");
   home.create("Betelguese");
   home.create("Andromeda");
   home.create("Aries");
   home.create("Omicron Cetus");
}


Figure 5. The results displayed in the demo application
The results displayed in the demo application

Directly remove Sol

The Directly remove Sol menu item in the Transaction Demo application provides an example of how to call transaction code from the Web application's perspective. Here you want some code in the Web tier to access the star entities directly and actually remove one of them, named Sol. The code in Listing 5 shows how this is done by using a UserTransaction. An InitialContext object, which is part of the Java Naming and Directory Interface (JNDI) API, is used to look up an instance of UserTransaction using the J2EE standard name .java:comp/UserTransaction. After it's acquired, it's used to start and commit a transaction, and if there are any errors, the transaction is rolled back.


Listing 5: Web tier transaction handling example
        
/**
* Remove the star Sol from the database by performing 
* the operation directly on the Star EJB instead of going 
* through the session bean.
* @throws NamingException if the user transaction cannot be found.
* @throws SystemException if the transaction cannot be used.
* @throws NotSupportedException if the transaction cannot be used.
*/
private void removeSol() throws NamingException, 
   NotSupportedException, SystemException {
      
InitialContext ctx = new InitialContext();
UserTransaction tx = null;
      
    try {

   // Look up the transaction
   tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");

   // Begin the transaction now
   tx.begin();
         
   StarLocal sun = 
                    StarUtil.getLocalHome().findByPrimaryKey("Sol");
      sun.remove();
         
      // We've succeeded, so commit the transaction
      tx.commit();
         
   } catch (Throwable e) {
      // An error occurred, so roll back.
      tx.rollback();
      e.printStackTrace();
   } finally {
      // Dispose of the initial context.
      if (ctx != null) {
         try {
            ctx.close();
         } catch (Throwable ex) {
         }
      }
   }
}


Use a stateless session bean for new transactions

If you look through the Transaction Demo source code, you find very little mention of transactions. This is because the Geronimo container is handling most of them in the background, as a good J2EE container should. Every stateless session bean method that is marked with a container transaction section in the deployment descriptor (ejb-jar.xml) is automatically provided with a CMT by the Geronimo EJB container. CMTs are a very good way to simplify your code. The stateless session bean with container-managed transactional methods, as described in Listing 5 and Listing 6, reduce the complexity involved with managing database entities. When you are operating on a single type of entity bean without any complex relations, simply marking the method with a transaction type of Required or RequiresNew is sufficient (see Listing 6 for the applicable DTD).


Listing 6. Excerpt from the ejb-jar 2.0 DTD
        
"The trans-attribute element specifies how the container 
must manage the transaction boundaries when delegating a
method invocation to an enterprise bean's business method.

The value of trans-attribute must be one of the following:

   <trans-attribute>NotSupported</trans-attribute>
   <trans-attribute>Supports</trans-attribute>
   <trans-attribute>Required</trans-attribute>
   <trans-attribute>RequiresNew</trans-attribute>
   <trans-attribute>Mandatory</trans-attribute>
   <trans-attribute>Never</trans-attribute>

Used in: container-transaction"

The Transaction Demo application sets up the transaction type using the XDoclet code generator. So if you examine the documentation comments surrounding the method in Listing 4, you find the @ejb-transaction type="Required" tag. The Required transaction type specifies that the session bean method requires a transaction to be present while its code is executing. If one does not exist, the container supplies one. If one is already present in the calling thread, that transaction is used.

The RequiresNew transaction type is different. If a transaction doesn't exist on the calling thread, one is created by the container, similar to the Required transaction type. However, if there is already a transaction on the calling thread, that transaction is suspended, and a new transaction is created and used. The calling transaction is then resumed.


Summary

You should now have a good idea of how to use transactions in a J2EE application server, with a Transaction Demo application designed to run under a Geronimo application server. You've also been given examples of how to set up CMTs using stateless session beans, and you've been shown how to create a transaction and manage its lifetime by obtaining an instance of the UserTransaction class. Now you can take advantage of using transactions with Geronimo to maintain data integrity.



Download

DescriptionNameSizeDownload method
Transaction demo applicationtransactions.zip34 KB HTTP | Download Director

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Author photo

Neal Sanche is a Java developer recently beached in the Microsoft® .NET world and fighting for any ties back to his old, comfortable roots. His experience includes development of several commercial J2EE applications, as well as several stand-alone Java applications. In his spare time, he writes music, takes photographs, and writes technical articles. Visit his Web site to see several examples of each.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology, WebSphere
ArticleID=95345
ArticleTitle=Transactions in the Geronimo application server
publish-date=10112005
author1-email=neal@nsdev.org
author1-email-cc=ruterbo@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers