13.3. CMT (Container Managed Transactions)
Dans les cas où la JBoss BPM Suite est incorporée dans une application qui est dans un conteneur qui permet de gérer les transactions lui-même (Container Managed Transactions - CMT), un gestionnaire de transactions spécialement dédié est fourni grâce à la classe
org.jbpm.persistence.jta.ContainerManagerTransactionManager. C'est parce que l'implémentation par défaut du gestionnaire de transactions de JBoss BPM Suite est basée sur la classe UserTransaction qui obtient le statut de la transaction. Cependant, certains serveurs d'applications en mode CMT ne permettent pas d'accéder à l'instance de UserTransaction à partir du JNDI.
Les opérations exécutées sur ce gestionnaire sont toutes non opérationnelles (NOOP) parce qu'elles ne peuvent pas affecter la CMT sous-jacent. La classe
ContainerManagedTransactionManager s'attend à ce que la transaction soit toujours active (renvoyant ACTIVE à la méthode getStatus()).
Note
Même si le conteneur gère des transactions, le conteneur doit être informé de toutes les exceptions qui se produisent pendant l'exécution d'instances de processus. Les exceptions levées par le moteur doivent être propagées jusqu'au conteneur pour pouvoir restaurer correctement les transactions.
Configurer le gestionnaire de transactions
Pour pouvoir utiliser le
ContainerManagedTransactionManager, il doit être inséré dans l'environnement avant que vous puissiez créer ou charger une session :
Environment env = EnvironmentFactory.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
env.set(EnvironmentName.TRANSACTION_MANAGER, new ContainerManagedTransactionManager());
env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, new JpaProcessPersistenceContextManager(env));
Ensuite, installer votre fournisseur de service JPA dans votre fichier
persistence.xml. Par exemple, si vous utilisez WebSphere d'IBM :
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
Disposer d'une KSession dans une CMT
Dans une CMT, vous ne devriez pas disposer d'une ksession directement (en utilisant la méthode
dispose()). Ce faisant provoquerait des exceptions à la fin de la transaction car le moteur de processus doit nettoyer l'état quand l'invocation est terminée
Utilisez plutôt la méthode
execute() de la classe spécialisée org.jbpm.persistence.jta.ContainerManagedTransactionDisposeCommand. Cette commande s'assure que la ksession sera supprimée lorsque la transaction sera effectivement terminée.
Cette méthode vérifie si la transaction est active. Si c'est le cas, elle délègue la phase
afterDisposal de la transaction au lieu de l'exécuter directement. S'il n'y a aucune transaction active, la ksession sera supprimée immédiatement.