Consideraciones sobre conexiones cuando se migran servlets, JavaServer Pages o enterprise beans de sesión
Si piensa actualizar a WebSphere Application Server Versión 7.0 o posterior y migrar las aplicaciones de la versión 1.2 de la especificación J2EE (Java™ 2 Platform, Enterprise Edition) a una versión posterior como, por ejemplo, la versión 1.4 o Java Platform, Enterprise Edition (Java EE), tenga en cuenta que el producto asigna conexiones que se pueden compartir y que no se pueden compartir de forma diferente para los componentes de aplicaciones posteriores a la versión 1.2. Para algunas aplicaciones, dicha diferencia puede significar una disminución del rendimiento.
Cambios del comportamiento adverso
Dado que WebSphere Application Server proporciona compatibilidad con versiones anteriores con módulos de aplicación codificados con la especificación J2EE 1.2, puede seguir utilizando orígenes de datos del estilo de la versión 4 cuando haga una migración a WebSphere Application Server Versión 7.0 o posterior. Siempre que configure orígenes de datos de la versión 4 únicamente para módulos J2EE 1.2, el comportamiento de los componentes de aplicación de acceso a datos no cambia.
Si está adoptando una versión posterior de la especificación J2EE junto con la migración a WebSphere Application Server Versión 7.0 o posterior, no obstante, el comportamiento de los componentes de acceso a datos puede cambiar. Especialmente, este riesgo se aplica a las aplicaciones que incluyen servlets, archivos JSP (JavaServer Page) o enterprise beans de sesión que se ejecutan dentro de las transacciones locales en conexiones que se pueden compartir. Un cambio en el comportamiento de los componentes de acceso a datos puede afectar desfavorablemente al uso de conexiones en dichas aplicaciones.
Esta modificación afecta a todas las aplicaciones que contienen los métodos siguientes:
- RequestDispatcher.include()
- RequestDispatcher.forward()
- Inclusiones de JSP (<jsp:include>)
Los síntomas del problema son:
- Las sesiones se cuelgan
- Tiempo de espera de sesión
- Se agotan las conexiones
El conmutador para asignar conexiones compartibles y no compartibles
Para módulos J2EE 1.2 que utilizan orígenes de datos de la versión 4, WebSphere Application Server emite conexiones no compartibles a archivos JSP, servlets y enterprise beans de sesión. Todos los demás componentes de aplicación emiten conexiones compartibles. No obstante, para módulos J2EE 1.3 y posteriores, el servidor de aplicaciones emite conexiones compartibles a todos los recursos nombrados lógicamente (recursos enlazados a referencias individuales) a no ser que especifique las conexiones como no compartibles en las referencias a recursos individuales. Utilizar conexiones compartibles en este contexto tiene los efectos siguientes:
- Ninguna de las conexiones recibidas y utilizadas fuera del ámbito de una transacción de usuario se devuelve a la agrupación de conexiones libres hasta que se devuelva el método encapsulado, incluso cuando el manejador emite una llamada close().
- Ninguna de las conexiones recibidas y utilizadas fuera del ámbito de una transacción de usuario se comparte con otras instancias de componentes (es decir, con otros servlets, archivos JSP o enterprise beans). Por ejemplo, el bean de sesión 1 obtiene una conexión y, a continuación, llama al bean de sesión 2 el cual también obtiene una conexión. Incluso aunque todas las propiedades sean idénticas, cada bean de sesión recibe su propia conexión.
Si no había previsto este cambio en el comportamiento de la conexión, el modo en que estructure el código de aplicaciones puede conducir a un uso excesivo de conexiones, especialmente en los casos de inclusiones de JSP, beans de sesión que se ejecutan dentro de transacciones locales en conexiones compartibles, rutinas RequestDispatcher.include(), rutinas RequestDispatcher.forward() o llamadas desde estos métodos a otros componentes. Por lo tanto, puede ocurrir que se cuelgue la sesión, caduque el tiempo de espera de la sesión o que haya una deficiencia en la conexión.
Escenario de ejemplo
Un servlet A obtiene una conexión, finaliza el trabajo, compromete la conexión y emite close() para la conexión. A continuación, el servlet A llama a RequestDispatcher.include() para incluir el servlet B, que realiza los mismos pasos que el servlet A. Dado que la conexión de servlet A no vuelve a la agrupación libre hasta que vuelve del método actual, ahora hay dos conexiones ocupadas. De este modo, es posible que se estén utilizando más conexiones de las que había planificado para su aplicación. Si no se tienen en cuenta estas conexiones para el valor de Número máximo de conexiones de la agrupación de conexiones, es posible que este comportamiento provoque una escasez de conexiones en la agrupación lo que produce que se generen excepciones ConnectionWaitTimeOutExceptions. Si no está habilitado el Tiempo de espera de la conexión o si se establece el valor de Tiempo de espera de la conexión en un período de tiempo prolongado, es posible que parezca que estas hebras se hayan colgado ya que están esperando conexiones que nunca se devuelven a la agrupación. Las hebras que esperan nuevas conexiones no devolverán nunca las que están utilizando actualmente si no hay conexiones nuevas disponibles.
Resolución
Para solucionar estos problemas:
- Utilice conexiones no compartidas.
Si utiliza una conexión no compartida y no está en una transacción de usuario, la conexión se devolverá a la agrupación libre cuando emita una llamada close(), (suponiendo que ha comprometido o retrotraído la conexión).
- Aumente el número máximo de conexiones.
Para calcular el número de conexiones necesarias, multiplique el número de hebras configuradas por el nivel más bajo de anidación de llamadas a componente (para aquellas llamadas que utilizan las conexiones). Consulte la sección Escenario de ejemplo para obtener una descripción del anidamiento de llamadas.