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:
- JSP includes (<jsp:include>)
Symptoms of the problem include:
- Session hang
- Session timeout
- Running out of connections
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:
- All connections that are received and used outside the scope of a user transaction are not returned to the free connection pool until the encapsulating method returns, even when the connection handle issues a close() call.
- All connections that are received and used outside the scope of a user transaction are not shared with other component instances (that is, other servlets, JSP files, or enterprise beans). For example, session bean 1 gets a connection and then calls session bean 2 that also gets a connection. Even if all properties are identical, each session bean receives its own connection.
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.
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.
To resolve these problems:
- 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).
- 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.
Exceptions pertaining to data access Unshareable and shareable connections