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.