13.3. Transações Gerenciadas por Contêiner

Nos casos em que o JBoss BPM Suite estiver inserido em um aplicativo que está em um contêiner que pode gerenciar as transações por si próprio (Transações Gerenciadas por Contêiner - CMT), um gerenciador de transação especial é fornecido usando a classe org.jbpm.persistence.jta.ContainerManagerTransactionManager. Isto é devido à implementação padrão do gerenciador de transação no JBoss BPM Suite ser baseada na classe UserTransaction que obtém o status de transação. No entanto, alguns servidores do aplicativo no modo CMT não permitem o acesso à instância UserTransaction a partir do JNDI.
As operações executadas nesse gerenciador são todas inoperantes, pois elas não podem afetar a CMT subjacente. A classe ContainerManagedTransactionManager espera que a transação esteja sempre ativa (retornando ACTIVE para o método getStatus()).

Nota

Apesar do contêiner gerenciar as transações, ele deve estar ciente de todas as exceções que ocorrem durante a execução da instância do processo. As exceções lançadas pelo mecanismo devem ser propagadas até o contêiner para que as transações sejam revertidas adequadamente.

Configurando o Gerenciador de Transação

Para configurar e usar ContainerManagedTransactionManager, é preciso que ele seja inserido no ambiente antes que você crie ou carregue uma sessão:
    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));
Depois, configure o Provedor JPA no seu arquivo persistence.xml. Por exemplo, se estiver usando IBM WebSphere:
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>

Descartando a KSession em uma CMT

Você não deve descartar a ksession diretamente em uma CMT (usando o método dispose()). Essa ação causa exceções na conclusão da transação, já que o Mecanismo de Processo precisa limpar o estado depois que a invocação tiver terminado.
Ao invés disto, utilize o método execute() da classe especializada org.jbpm.persistence.jta.ContainerManagedTransactionDisposeCommand. O uso desse comando garante que a ksession seja descartada quando a transação estiver, de fato, concluída.
Esse método verifica se a transação está ativa. Se sim, ele delega o descarte à fase afterDisposal da transação, ao invés de executá-lo diretamente. Caso não haja nenhuma transação ativa, a ksession é descartada imediatamente.