Cycle de vie d'une connexion
Un objet ManagedConnection est toujours dans l'un des trois états suivants : DoesNotExist, InFreePool ou InUse.
L'état d'une connexion avant sa création doit être DoesNotExist (n'existe pas). Après sa création, elle peut être soit dans l'état InUse (en cours d'utilisation), soit dans l'état InFreePool (dans le pool de connexions libres), selon qu'elle est ou non allouée à une application.
- l'application a appelé la méthode getConnection de la source de données ou de la fabrique de connexions (condition getConnection) ;
- une connexion libre, avec des propriétés concordantes, est disponible dans le pool (condition freeConnectionAvailable) ;
- l'une des deux conditions suivantes est vérifiée :
- la demande getConnection() est émise pour le compte d'une référence de ressource qui est marquée "non partageable" (unshareable) ;
- la demande getConnection() est émise pour le compte d'une référence de ressource qui est marquée "partageable" (shareable), mais aucune connexion partageable en cours d'utilisation ne possède les mêmes propriétés.
InFreePool > InUse: getConnection AND freeConnectionAvailable AND NOT(shareableConnectionAvailable)Voici une liste de conditions de garde avec leur description.
Condition | Description |
---|---|
ageTimeoutExpired | La connexion est plus ancienne que sa limite d'âge définie par la propriété ageTimeout. |
close | L'application appelle méthode close sur l'objet Connection. |
fatalErrorNotification | Une connexion vient juste de rencontrer une erreur fatale. |
freeConnectionAvailable | Une connexion ayant des propriétés concordant avec celles spécifiées dans la demande est disponible dans le pool de connexions libres. |
getConnection | L'application appelle la méthode getConnection sur un objet source de données ou fabrique de connexions. |
markedStale | Une connexion est marquée "périmée" (stale), généralement en réponse à une notification d'erreur fatale. |
noOtherReferences | Il n'y a qu'un seul descripteur de connexion associé à la connexion gérée (objet ManagedConnection) et le service de transaction ne détient aucune référence à cet objet. |
noTx | Aucune transaction n'est en vigueur. |
poolSizeGTMin | La taille du pool de connexions est supérieure à la taille minimale configurée (nombre minimal de connexions). |
poolSizeLTMax | La taille du pool de connexions est inférieure à la taille maximale configurée (nombre maximal de connexions). |
shareableConnectionAvailable | La demande getConnection() porte sur une connexion partageable, et une telle connexion, ayant les propriétés demandées, est en cours d'utilisation et disponible pour être partagée. |
TxEnds | La transaction a pris fin. |
unshareableConnectionRequest | La demande getConnection() porte sur une connexion non partageable. |
unusedTimeoutExpired | Une connexion est disponible dans le pool et est restée inutilisée pendant une durée supérieure à la valeur de son délai d'inutilisation. |
Obtention de connexions
Les premières transitions décrites ici sont celles dans lesquelles l'application demande une connexion à une source de données ou à une fabrique de connexions. Dans certains de ces cas de figure, le résultat est une nouvelle connexion à la base de données. Dans d'autres cas, la connexion peut être obtenue du pool de connexions ou partagée avec une autre demande de connexion.getConnection AND NOT(freeConnectionAvailable) AND poolSizeLTMax AND (NOT(shareableConnectionAvailable) OR unshareableConnectionRequest)
- L'application appelle la méthode getConnection() sur la source de données ou la fabrique de connexions.
- Aucune connexion n'est disponible dans le pool de connexions libres (condition NOT(freeConnectionAvailable)).
- La taille du pool de connexions est inférieure à la taille maximale configurée (condition poolSizeLTMax).
- La demande porte sur une connexion partageable et aucune connexion partageable, déjà en cours d'utilisation et présentant les mêmes propriétés de partage, n'est disponible (condition NOT(shareableConnectionAvailable)) OU la demande porte sur une connexion non partageable (condition unshareableConnectionRequest).
Toutes les connexions sont initialement dans l'état DoesNotExist et ne sont créées que lorsque l'application demande une connexion. La taille du pool est initialement à zéro et augmente jusqu'au maximum configuré à mesure que les applications demandent de nouvelles connexions. Au démarrage du serveur, le pool n'est pas créé avec le nombre minimal de connexions configuré.
Si la demande porte sur une connexion partageable et qu'une telle connexion présentant les mêmes propriétés de partage est déjà utilisée par l'application, elle est partagée par plusieurs autres demandes de connexion. Dans ce cas, aucune nouvelle connexion n'est créée. Pour les utilisateurs de l'API JDBC, ces propriétés de partage sont le plus souvent l'ID utilisateur/mot de passe et le contexte de transaction ; pour les utilisateurs de l'interface CCI (Common Client Interface) de l'adaptateur de ressources, il s'agit généralement de la spécification de connexion (ConnectionSpec), du sujet (Subject) et du contexte de transaction.
InFreePool > InUse: getConnection AND freeConnectionAvailable AND (unshareableConnectionRequest OR NOT(shareableConnectionAvailable))
- l'application a émis un appel getConnection() ;
- une connexion utilisable est disponible dans le pool (condition freeConnectionAvailable) ;
- l'un des conditions suivantes est vérifiée :
- la demande porte sur une connexion non partageable (condition unshareableConnectionRequest) ;
- aucune connexion ayant les mêmes propriétés de partage n'est déjà utilisée dans la transaction (condition NOT(shareableConnectionAvailable)).
Chaque fois qu'une demande de connexion peut être satisfaite par une connexion du pool, aucune nouvelle connexion à la base de données n'est créée. Par conséquent, s'il n'y a jamais plus d'une connexion du pool utilisée à la fois (et ce quel que soit le nombre d'applications), la taille du pool n'augmente jamais au-delà de 1. Cette valeur peut être inférieure au nombre minimal de connexions configuré pour le pool. L'un des cas où le pool croît jusqu'au nombre minimal de connexions se présente lorsque l'application émet simultanément plusieurs demandes de connexion qui doivent conduire à la création d'une nouvelle connexion.
InUse > InUse: getConnection AND ShareableConnectionAvailable
Cette transition indique que si une application demande une connexion partageable (getConnection) avec les mêmes propriétés de partage que celles d'une connexion déjà en cours d'utilisation (ShareableConnectionAvailable), cette dernière est partagée.
Restitution des connexions après utilisation
Toutes les transitions vues précédemment concernent l'obtention de connexions à l'usage de l'application. Avec cet objectif, les transitions conduisent à la fermeture d'une connexion et soit à sa restitution au pool de connexions libres, soit à sa destruction. Chaque connexion doit être explicitement fermée par l'application au moyen d'un appel de la méthode close() de l'objet connexion (notez que la connexion obtenue par l'utilisateur est en réalité un descripteur de connexion). Dans la plupart des cas, il en résulte la transition suivante :InUse > InFreePool: (close AND noOtherReferences AND NoTx AND UnshareableConnection) OR (ShareableConnection AND TxEnds)
- Si l'application ou le conteneur appelle la méthode close() (condition close) et qu'il n'y a pas de référence (condition noOtherReferences) détenue soit par l'application (condition de partage d'application), soit par le gestionnaire de transactions (qui détient une référence lorsque la connexion est enrôlée dans une transaction - condition NoTx), l'objet connexion est renvoyé au pool de connexions libres.
- Si la connexion a été enrôlée dans une transaction, mais que le gestionnaire de transactions met fin à cette transaction (condition txEnds) et que la connexion était partageable (condition ShareableConnection), elle est fermée et renvoyée au pool de connexions libres.
Lorsque l'application appelle close() sur une connexion, elle la renvoie au pool de connexions libres ; elle ne ferme pas la connexion au magasin de données. Lorsque l'application appelle close() sur une connexion qui est en cours de partage, la connexion n'est pas renvoyée au pool de connexions libres. Ce n'est que lorsque la dernière référence à la connexion est supprimée par l'application et que la transaction est terminée que la connexion est renvoyée au pool. Les applications qui utilisent des connexions non partageables doivent fermer celles-ci à bon escient. Faute de quoi le pool de connexions peut ne plus avoir de connexions disponibles et les applications s'exécutant sur le serveur peuvent se trouver dans l'impossibilité d'obtenir une connexion.
Lorsque l'application appelle close() sur une connexion enrôlée dans une transaction, la connexion n'est pas renvoyée au pool de connexions libres. Comme le gestionnaire de transactions doit aussi détenir une référence à l'objet Connection, la connexion ne peut pas être renvoyée au pool avant que la transaction ne soit terminée. Dès lors qu'une connexion est enrôlée dans une transaction, elle ne peut pas être utilisée dans une autre transaction par une autre application tant que la transaction n'est pas achevée.
InUse > DoesNotExist: close AND markedStale AND NoTx AND noOtherReferences
Cette transition indique que si l'application appelle close() sur la connexion et que celle-ci a été marquée "périmée" lors de l'étape de nettoyage du pool (condition markedStale), la connexion au magasin de données est fermée et n'est pas renvoyée au pool.
Enfin, les connexions au magasin de données peuvent être fermées et supprimées du pool.
- Si une notification d'erreur fatale est reçue de l'adaptateur de ressources (ou de la source de données). Une notification d'erreur fatale (condition FatalErrorNotification) est reçue de l'adaptateur de ressources lorsqu'il est arrivé quelque chose à la connexion qui la rend inutilisable. Toutes les connexions actuellement présentes dans le pool sont alors détruites.
- Si la connexion est restée dans le pool plus longtemps que son délai d'inutilisation (condition UnusedTimeoutExpired) et si la taille du pool est supérieure au nombre minimal de connexions (condition poolSizeGTMin), la connexion est retirée du pool et détruite. Ce mécanisme permet de ramener le pool à sa taille minimale lorsque la demande de connexions chute.
- Si une limite d'âge (propriété ageTimeout) est configurée et qu'une connexion donnée est plus ancienne que cette limite. Ce mécanisme offre un moyen de recycler les connexions en fonction de leur âge.