Connection considerations when migrating servlets, JSP, or enterprise session beans

If we plan to upgrade to WAS v6.1 or later, and migrate applications from version 1.2 of the J2EE specification to a later version, such as 1.4 or Java EE, be aware that the product allocates shareable and unshareable connections differently for post-version 1.2 application components. For some applications, that difference can result in performance degradation.


Adverse behavior changes

Because WebSphere Application Server provides backward compatibility with application modules coded to the J2EE 1.2 specification, we can continue to use Version 4 style data sources when you migrate to WAS v6.1 or later As long as you configure Version 4 data sources only for J2EE 1.2 modules, the behavior of your data access application components does not change.

If we are adopting a later version of the J2EE specification along with the migration to WAS v6.1 or later, however, the behavior of the data access components can change. Specifically, this risk applies to applications that include servlets, JavaServer Page (JSP) files, or enterprise session beans that run inside local transactions over shareable connections. A behavior change in the data access components can adversely affect the use of connections in such applications.

This change affects all applications containing the following methods:

Symptoms of the problem include:

We can also experience these symptoms with applications containing the components and methods described previously if you are upgrading from J2EE 1.2 modules within WAS v6.1 or later.


The switch in allocating shareable and unshareable connections

For J2EE 1.2 modules using Version 4 data sources, WebSphere Application Server issues non-sharable connections to JSP files, servlets, and enterprise session beans. All of the other application components are issued shareable connections. However, for J2EE 1.3 and later modules, the application server issues shareable connections to all logically named resources (resources bound to individual references) unless specified the connections as unshareable in the individual resource-references. Using shareable connections in this context has the following effects:

If we do not anticipate this change in the connection behavior, the way you structure the application code can lead to excessive connection use, particularly in the cases of JSP includes, session beans that run inside local transactions over shareable connections, RequestDispatcher.include() routines, RequestDispatcher.forward() routines, or calls from these methods to other components. Consequently, we can experience session hang, session timeout, or connection deficiency.


Example scenario

Servlet A gets a connection, completes the work, commits the connection, and calls close() on the connection. Next, servlet A calls the RequestDispatcher.include() to include servlet B, which performs the same steps as servlet A. Because the servlet A connection does not return to the free pool until it returns from the current method, two connections are now busy. In this way, more connections might be in use than you intended in the application. If these connections are not accounted for in the Max Connections setting on the connection pool, this behavior might cause a lack of connections in the pool, which results in ConnectionWaitTimeOut exceptions. If the connection wait timeout is not enabled, or if the connection wait timeout is set to a large number, these threads might appear to hang because they are waiting for connections that are never returned to the pool. Threads waiting for new connections do not return the ones they are currently using if new connections are not available.


Resolution

To resolve these problems:

  1. Use unshared connections.

    If we use an unshared connection and are not in a user transaction, the connection is returned to the free pool when you issue a close() call (assuming you commit or roll back the connection).

  2. Increase the maximum number of connections.

    To calculate the number of required connections, multiply the number of configured threads by the deepest level of component call nesting (for those calls that use connections). See the Example scenario section for a description of call nesting.


Related concepts

  • Exceptions pertaining to data access
  • Unshareable and shareable connections