|
|
YOUR FEEDBACK
SOA World Conference
Virtualization Conference $200 Savings Expire May 16, 2008... – Register Today! Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Data Centers
Using the Unshareable DataSource in WebSphere Application Server 5.0
By: Jian Tang
Digg This!
In Java 2 Enterprise Edition (J2EE) 1.3, a new concept of a resource sharing scope has been introduced. A resource sharing scope can be either shareable or unshareable, the default being shareable. If the resource is configured as shareable, applications can share connections to this resource; if the resource is unshareable, connections will not be shared. Of all resources, the datasource is the most widely used. This article focuses on how to use unshareable datasources in WebSphere Application Server (WAS) 5.0. A resource is configured as shareable by setting <res-sharing-scope> of the deployment descriptor to "Shareable". If a datasource is configured as unshareable in WAS 5.0 by setting <res-sharing-scope> to "Unshareable", every getConnection() call will access a connection handle with a different physical connection, even within the same sharing scope (I will discuss this in greater detail later). There is a one-to-one relationship between the connection handle and the physical connection to the datasource. In other words, there is an exclusive physical connection for each connection handle's use. If a datasource is configured as shareable, multiple getConnection() calls may access different connection handles with the same physical connection to the datasource in the same sharing scope. In other words, these connection handles may share the same physical connection. There are several reasons for using unshareable connections. The first is to isolate unexpected behavior, for example, when you don't want other Enterprise JavaBeans (EJB) to access an EJB's physical connection, in order to avoid unexpected behavior related to the connection. The second reason is that some applications may need to make changes to connection attributes that are not allowed for shareable connections. One example of these attributes is the readOnly attribute. Other examples include character settings, localization configurations, etc. If applications fall into any of these categories, unshareable connections should be used. Since all connections are shared in WAS 4.0, some programming models that worked in WAS 4.0 might not work without modification in WAS 5.0 if these applications use unshareable data sources. In this article, I will discuss which models work and which won't work when unshareable data sources are used.
Problems with Unshareable Connections A sharing boundary can be a global transaction (either a user transaction or a container-managed transaction), or a Local Transaction Containment (LTC). Notice that an LTC is different from a Resource Manager Local Transaction (RMLT), which is a resource's view of a local transaction. An LTC is a scope in which multiple RMLTs may be accessed in WAS 5.0. An example of an LTC is an execution of a bean method with the transaction attribute NotSupported, while setting a connection's autocommit attribute to false and later committing the connection is an example of an RMLT. To better understand the case in which a data source is unshareable, assume we have two getConnection() calls to the same datasource within a sharing boundary. If the first connection is not closed before the second getConnection() is called, the second call will definitely get a different physical connection. What if the first connection is closed before the second getConnection() is called? Will the second connection have a different physical connection from the first connection, or will they have the same physical connection? Notice that LTC and global transactions handle this differently. In LTC, when the first connection is closed and there is no outstanding work associated with this connection (either this connection never did any work, or the work has been committed or rolled back), the physical connection is released back to the connection pool. When the second getConnection() is called, a free connection is picked up from the connection pool. Therefore, the same physical connection may be used to service the request. However, in global transactions, when the first connection is closed, the physical connection is not released since the global transaction has not completed. The second getConnection() will definitely access a different physical connection. Therefore, if a datasource is configured as unshareable, connections will not be shared within a sharing boundary. This means some applications that work in WAS 4.0 won't work in WAS 5.0 if they use unshareable datasources. The following code is an example of an application that might not work with an unshareable datasource.
userTransaction.begin(); This code works in WAS 4.0 without any problem, because all the datasources in WAS 4.0 are shareable. In this example, there is no difference between the connection attributes, and two instances of getConnection() are called within one sharing boundary, in this case a user transaction. Therefore, two connection handles, conn1 and conn2, will share the same physical connection. Although from the user's point of view, there are two connections, conn1 and conn2, doing different work, they are actually using the same physical connection to talk to the datasource. If the data source is configured as unshareable and the same code is executed in WAS 5.0, connection handles conn1 and conn2 will have different physical connections. The application may fail in one of the two following scenarios: 1. If the datasource does not support XA transaction, i.e., the datasource is a non-XA-capable datasource, such as an implementation of java.sql.ConnectionPoolDataSource, the application will fail because two non-XA-capable resources are not allowed to be enlisted in one global transaction. This will cause WAS 5.0 to throw a SQLException that includes "javax.resources.ResourceException: enlist: caught exception". There will also be a more detailed exception message in the log file: "Method enlist caught java.lang. IllegalStateException [specific exception stack trace] while trying to enlist resources from datasource [datasource JNDI name] with the Transaction Manager for the current transaction, and threw an Exception." 2. Even if the datasource supports XA transaction, if stmt1 tries to insert a record and stmt2 tries to update the same record, it will lead to database deadlock in some circumstances, for example, when the connection isolation level is TRANSACTION_REPEATABLE_ READ. In this case, you can either see an exception thrown from the database back end indicating a deadlock, or a javax. transaction. TransactionRolledBackException after the transaction is timed out. You should pay careful attention to your applications if you want to use unshareable datasources. Watch out for applications that have the following two characteristics: (1) an instance of global transaction; (2) two or more getConnection() calls within this global transaction.
Existing Programming Models For servlets and session beans, there are situations in which applications that work in WAS 4.0 won't work in WAS 5.0. The example shown earlier is a typical one. For BMP beans, if the datasource is configured as unshareable, it is possible that programming models that work in WAS 4.0 won't work in 5.0. To clarify these situations, let's have a look at some programming models that may not work in WAS 5.0.
Many BMP bean developers use the get/use/close model in every method. According to this model, in every business method, such as ejbLoad(), ejbcreate(), and ejbStore(), to name a few, connections are used in the following way:
This model has many advantages; it is easy to write, understand, and maintain. In fact, if the datasource is always shareable, this get/use/close model will work perfectly. However, if the datasource is unshareable, we will have the same problem as with the application shown earlier. Consider creating a BMP bean with the transaction attribute set to Required in a user transaction. As you know, creating a BMP bean requires two methods, ejbCreate() and ejbStore(), to be called in this transaction. If the get/use/close model is used, it will end up trying to access two physical connections within one global transaction. If the datasource is non-XA-capable, WAS 5.0 won't let the second connection's resource be enlisted in the transaction. Even if the datasource supports XA, there might be a deadlock, since usually ejbStore() updates the record created in ejbCreate().
Recommended Programming Models
Servlets
Session Beans A session bean can be stateful or stateless. Stateful session beans can contain conversational states, while stateless session beans cannot. Since stateless session beans cannot contain conversational states, you should not cache the connection in the bean class. Therefore, we can follow the get/use/close connection usage pattern in every method. Session bean users should be aware that there is a getConnection() called in every method of a stateless session bean if that method accesses a datasource. If you try to group several methods in one global transaction, you should be aware of the potential problems. For stateful session beans, you can cache the connection in the session bean class. You can get the connection in the setEntityContext() method and close the connection in ejbRemove(). Therefore, all methods in this stateful session bean use the same connection if the session bean accesses only one datasource. However, in this case you should call ejbRemove() after you finish using the session bean. Otherwise, the connection will be leaked in the system. There can be some improvements on the stateful session bean to avoid this problem. A container-managed transaction stateful session bean can implement the javax.ejb.SessionSynchronization interface. With this interface, "the afterBegin notification signals a session bean instance that a new transaction has begun. The container invokes this method before the first business method within a transaction (which is not necessarily at the beginning of the transaction). The afterCompletion notification signals that the current transaction has completed," according to the Enterprise JavaBeans 2.0 Specification. Therefore, you can get the connection in the afterBegin() method and close it in the afterCompletion(boolean) method so you won't have any connection-leaking problems. Similarly, if your stateful session bean is a bean-managed transaction session bean, the bean can get the connection after the user transaction is started and close the connection before the user transaction is committed or rolled back. For these reasons, the recommended connection usage pattern for session beans is as described in Table 1.
BMP Beans The simplest way to cache the connection handle in BMP is to get the connection in the setEntityContext() method and close it in unsetEntity Context(). This guarantees that one connection is used across this bean's life cycle. If in some business methods you want to access another datasource, you can simply get another connection. However, you should make sure both datasources support XA transaction. If this BMP bean accesses only one datasource, a non-XA-capable datasource can be used. The EJB specification states that setEntityContext() and unsetEntityContext() can only access EntityContext methods [getEJBHome() and getEJBLocalHome()], and JNDI access to java:comp/env. It also says, "if an entity bean instance attempts to access a resource manager or an enterprise bean, and the access is not allowed, the behavior is undefined by the EJB architecture." Fortunately, WAS 5.0 allows you to access a resource manager in all methods. Therefore, we don't have any problem getting the connection in setEntityContext() and closing it in unsetEntityContext(). The programming models recommended above are also applicable when the datasource is configured as shareable. In fact, caching connections to avoid calling getConnection() several times can improve performance. Therefore, if you require high performance from your applications, you should cache connections.
Summary
References: WEBSPHERE LATEST 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 BREAKING WEBSPHERE NEWS
|
|||||||||||||||||||||||||||||