Ciclo vital de la conexión
Un objeto ManagedConnection está siempre en uno de estos tres estados: DoesNotExist, InFreePool o InUse.
Antes de crear una conexión, debe estar en estado DoesNotExist. Después de crear la conexión, puede estar en estado InUse o InFreePool, dependiendo de si se le ha asignado a una aplicación o no.
- la aplicación ha llamado al método getConnection() de la fábrica de conexiones o del origen de datos (la condición getConnection)
- hay disponible una conexión libre en la agrupación con las propiedades coincidentes (la condición freeConnectionAvailable)
- y una de las siguientes dos condiciones es verdadera:
- la solicitud getConnection() actúa en nombre de una referencia de recursos marcada como no compartible
- la solicitud getConnection() actúa en nombre de una referencia de recursos marcada como compartible, pero no se está utilizando ninguna conexión compartible con las mismas propiedades.
InFreePool > InUse: getConnection AND freeConnectionAvailable AND NOT(shareableConnectionAvailable)A continuación se incluye una lista de condiciones de vigilancia y sus descripciones.
Condición | Descripción |
---|---|
ageTimeoutExpired | La conexión es anterior a su valor ageTimeout. |
close | La aplicación llama al método close en el objeto Connection. |
fatalErrorNotification | Una conexión acaba de experimentar un error grave. |
freeConnectionAvailable | Una conexión con las propiedades coincidentes está disponible en la agrupación libre. |
getConnection | La aplicación llama al método getConnection en un objeto de origen de datos o fábrica de conexiones. |
markedStale | La conexión está marcada como en punto muerto, normalmente como respuesta a una notificación de error muy grave. |
noOtherReferences | Sólo hay un manejador de conexiones con la conexión gestionada, y el servicio de transacciones no está manteniendo una referencia con la conexión gestionada. |
noTx | No hay ninguna transacción activada. |
poolSizeGTMin | El tamaño de la agrupación de conexiones es mayor que el tamaño de agrupación mínimo (número mínimo de conexiones) |
poolSizeLTMax | El tamaño de la agrupación es menor que el tamaño de agrupación máximo (número máximo de conexiones) |
shareableConnectionAvailable | La solicitud getConnection() es para una conexión compartible y se está utilizando una con propiedades coincidentes que está disponible para compartir. |
TxEnds | La transacción ha finalizado. |
unshareableConnectionRequest | La solicitud getConnection() es para una conexión no compartible. |
unusedTimeoutExpired | La conexión está en la agrupación libre y no está siendo utilizada después del valor de tiempo de espera no utilizado. |
Obtención de conexiones
Las primeras transacciones que se describen son aquéllas en las que la aplicación solicita una conexión desde un origen de datos o una fábrica de conexiones. En algunos de estos casos, se produce una nueva conexión a la base de datos. En otros, la conexión se puede recuperar desde la agrupación de conexiones o compartir con otra solicitud de conexión.getConnection AND NOT(freeConnectionAvailable) AND poolSizeLTMax AND (NOT(shareableConnectionAvailable) OR unshareableConnectionRequest)
- La aplicación llama al método getConnection() en el origen de datos o en la fábrica de conexiones
- No hay ninguna conexión disponible en la agrupación libre (NOT(freeConnectionAvailable))
- El tamaño de la agrupación es menor que el tamaño de agrupación máximo (poolSizeLTMax)
- Si la solicitud es de una conexión compartible y no se está utilizando todavía ninguna conexión compartible con las mismas propiedades de compartimiento (NOT(shareableConnectionAvailable)) O la solicitud es de una conexión no compartible (unshareableConnectionRequest)
Todas las conexiones empiezan en el estado DoesNotExist y sólo se crean cuando la aplicación solicita una conexión. La agrupación crece de 0 al número máximo de conexiones a medida que las aplicaciones solicitan las nuevas conexiones. La agrupación no se crea con el número mínimo de conexiones cuando se inicia el servidor.
Si la solicitud es de una conexión compartible y la aplicación ya está utilizando un conexión con las mismas propiedades de compartimiento, la conexión es compartida por dos o más solicitudes de conexión. En este caso, no se crea una nueva conexión. Para los usuarios de la API de JDBC, las propiedades de compartimiento son normalmente ID de usuario/contraseña y contexto de transacción; para los usuarios de la CCI (Common Client Interface) del adaptador de recursos, normalmente son ConnectionSpec, sujeto y contexto de transacción.
InFreePool>InUse: getConnection AND freeConnectionAvailable AND (unshareableConnectionRequest OR NOT(shareableConnectionAvailable))
- la aplicación ha emitido una llamada getConnection()
- hay disponible una conexión para su uso en la agrupación de conexiones (freeConnectionAvailable),
- y una de las siguientes condiciones es verdadera:
- la solicitud es de una conexión no compartible (unsharableConnectionRequest)
- no se está utilizando ninguna conexión con las mismas propiedades de compartimiento en la transacción. (NOT(sharableConnectionAvailable)).
Toda solicitud de conexión que pueda satisfacer una conexión de la agrupación libre no da como resultado una nueva conexión a la base de datos. Por lo tanto, si las distintas aplicaciones no utilizan nunca más de una conexión de la agrupación a la vez, la agrupación no aumentará su tamaño por encima de uno. Este valor puede ser inferior al número mínimo de conexiones especificado para la agrupación. Una forma de que la agrupación aumente al número mínimo de conexiones es que la aplicación tenga varias solicitudes simultáneas de conexión que puedan dar lugar a una nueva conexión.
InUse>InUse: getConnection AND ShareableConnectionAvailable
Esta transición indica que si una aplicación solicita una conexión compartible (getConnection) con las mismas propiedades de compartimiento que otra conexión que se esté utilizando (ShareableConnectionAvailable), se compartirá la conexión existente.
Devolución de conexiones
Todas las transiciones descritas anteriormente parten de la obtención de una conexión para el uso de la aplicación. Con este objetivo, las transiciones dan como resultado el cierre de una conexión, y su devolución a la agrupación libre o su destrucción. Las aplicaciones deberían cerrar explícitamente las conexiones (nota: la conexión que se devuelve al usuario es realmente un manejador de conexiones) llamando a close() en el objeto de conexión. En la mayoría de los casos, esta acción da como resultado la siguiente transición:InUse>InFreePool: (close AND noOtherReferences AND NoTx AND UnshareableConnection) OR (ShareableConnection AND TxEnds)
- Si la aplicación o el contenedor llama a close() (produce la condición de cierre) y no existen referencias (la condición noOtherReferences) de la aplicación (en la condición de compartimiento de aplicaciones) o del gestor de conexiones (en la condición NoTx, lo que significa que el gestor de transacciones mantiene una referencia cuando se incluye la conexión en una transacción), el objeto de conexión se devuelve a la agrupación libre.
- Si la conexión se ha incluido en una transacción, pero el gestor de transacciones finaliza la transacción (la condición txEnds), y la conexión era una conexión compartible (la condición ShareableConnection), la conexión se cierra y se devuelve a la agrupación.
Cuando la aplicación llama a close() en una conexión, la conexión se devuelve a la agrupación de conexiones libres; no se cierra la conexión en el origen de datos. Cuando la aplicación llama a close() en una conexión compartida actualmente, la conexión no se devuelve a la agrupación libre. Sólo después de que la aplicación deje de mantener la última referencia a la conexión, y finalice la transacción, la conexión se devuelve a la agrupación. Las aplicaciones que utilizan conexiones no compartibles deben procurar cerrar las conexiones periódicamente. Si no se hace así, la agrupación se puede quedar sin conexiones, por lo que será imposible obtener una conexión para las aplicaciones que se ejecuten en el servidor.
Cuando la aplicación llama a close() en una conexión incluida en una transacción, la conexión no se devuelve a la agrupación libre. Como el gestor de transacciones también debe mantener una referencia al objeto de conexión, la conexión no se puede devolver a la agrupación libre hasta que finalice la transacción. Una vez incluida una conexión en una transacción, no podrá ser utilizada por ninguna otra aplicación en otras transacciones hasta que haya finalizado dicha transacción.
InUse>DoesNotExist: close AND markedStale AND NoTx AND noOtherReferences
Esta transición indica que si la aplicación llama a close() en la conexión, y la conexión se ha marcado como en punto muerto durante el paso de limpieza de la agrupación (markedStale), el objeto de conexión se cierra para el almacén de datos y no se devuelve a la agrupación.
Por último, puede cerrar conexiones con el almacén de datos y eliminarlas de la agrupación.
- Si se recibe una notificación de error grave desde el adaptador de recursos (o desde el origen de datos). La notificación de error grave (FatalErrorNotification) se recibe desde el adaptador de recursos cuando la conexión se vuelve inutilizable debido a alguna razón. Todas las conexiones que hay actualmente en la agrupación libre se destruyen.
- Si la conexión está en la agrupación libre un período de tiempo mayor que el tiempo de espera no utilizado (UnusedTimeoutExpired) y el tamaño de la agrupación es mayor que el número mínimo de conexiones (poolSizeGTMin), la conexión se eliminará de la agrupación libre y se destruirá. Este mecanismo permite a la agrupación volver al tamaño mínimo cuando disminuye la demanda de conexiones.
- Si se configura el tiempo de espera superado y una conexión específica es anterior al tiempo de espera. Este mecanismo facilita una forma de reciclar las conexiones según la antigüedad.