Transaction is not active
Rédigé par gorki Aucun commentaireLe problème :
Lors de l'exécution d'un service, l'erreur suivante apparait :
javax.resource.ResourceException: IJ000459: Transaction is not active
Plusieurs liens internet en parle, c'est systématiquement lié à JBoss puisque c'est lui qui gère ce niveau transactionnel en mode container et que le code IJ... c'est du JBoss.
Solution :
En court : Bien tracer toutes les erreurs, une erreur précédent celle-ci est survenue et a mis la transaction en rollback-only (on pourrait rapprocher ce problème de ceci).
En long :
Contexte d'exécution : JBoss 7.1.1, Hibernate 4.1.6
- Si une exception est remontée par hibernate, elle met par défaut la transaction au statut ABORT
- L’erreur de haut niveau lorsqu’on essaye d’utiliser une transaction avec le statut ABORT (en lecture ou écriture) est : « Could not open connection »
Ce genre de cas arrive lorsque la gestion d’erreur est mal codée (le service de haut niveau ne se termine par immédiatement et on essaye de mettre à jour quelque chose en base…)
Scénario d'exemple :
-
1ere erreur hibernate :
- EJB Invocation failed on component
- javax.persistence.OptimisticLockException
- Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
-
2eme erreur :
- EJB Invocation failed on component
- javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Could not open connection
- org.hibernate.exception.GenericJDBCException: Could not open connection
- java.sql.SQLException: javax.resource.ResourceException: IJ000460: Error checking for a transaction
- javax.resource.ResourceException: IJ000460: Error checking for a transaction
- javax.resource.ResourceException: IJ000459: Transaction is not active: tx=TransactionImple <.... ActionStatus.ABORT_ONLY >
Lorsque l’exception numéro 1 est arrivée, votre transaction devient inutilisable, pas la peine d'essayer de faire autre chose avec.
Exemple de code incorrect :
Pour tous les objets Try { Mise à jour objet } catch() { Logger l’erreur. // Pour rappel, on loggue bien sur les informations fonctionnelles ET techniques (pile d’exception) } Fpour Mise à jour d’un statut OK ou KO <= impossible si la ligne « mise à jour objet » à mis la transaction en rollback.
Solution pour cet exemple :
- sortir de la boucle en remontant l'erreur, ne pas mettre à jour de statut (rien n’est mis à jour)
- sortir de la boucle en remontant l'erreur, les statuts sont stockés au fur et à mesure et mis à jour dans nouvelle transaction
- tracer l’erreur, continuer la boucle, les statuts sont mis à jour en même temps que l'objet
- et bien d'autres cas possibles suivant votre fonctionnel...