Transação
Esta funcionalidade utiliza os recursos do CDI para interceptar e delegar o tratamento adequado das transações
para quem é de direito. Em outras palavras, não reinventamos a roda. Criamos algumas estratégias de delegação e
controle de transação com base no que está sendo mais utilizado no mercado, algumas mais simples de configurar,
outras mais completas para utilizar.
Além de plugar e usar as estratégias prontas que fizemos para você, é possível também criar a sua. Vai que você
precise de algo que não pensamos ainda. O importante é que você tenha opções, e uma das opções também é não
utilizar a nossa solução. Caso você esteja utilizando o Demoiselle Framework em conjunto
com outro framework (tais como o JBoss Seam, Spring ou Google Guice) que ofereça o controle de transação,
você pode usá-lo também. Viva a liberdade de escolha!
Neste capítulo apresentaremos para você como usar a nossa solução de controle de transação, as estratégias
prontas que oferecemos e a criação de sua própria estratégia.
Configurando
Para um correto funcionamento do Demoiselle é necessário inserir o interceptador de transação no arquivo src/main/WEB-INF/beans.xml.
br.gov.frameworkdemoiselle.internal.interceptor.TransactionalInterceptor
]]>
Métodos transacionais
Vamos começar pelo mais importante: como declarar os métodos como transacionais? Como informar ao
Demoiselle Framework que o método deve participar da sessão transacional?
A resposta é muito simples, anote seu método com @Transactional.
Se você desejar que todos os métodos de sua classe sejam transacionais, anote diretamente a classe:
Neste exemplo, os métodos inserir(), alterar() e
excluir() da classe Simples participarão do contexto transacional.
E se acontecer uma Exception?
Caso ocorra uma exceção na execução de um método transacional o mecanismo fará rollback na transação
automaticamente. É possível mudar este comportamento utilizando exceções de aplicação.
O objeto Transaction
Para ter acesso à instância da transação corrente, basta injetá-la em sua classe.
Escolha a estratégia adequada
Para o controle transacional funcionar corretamente é preciso escolher a estratégia mais adequada para o seu
caso. Não existe a bala de prata, você tem que avaliar a melhor estratégia para o seu projeto.
Você pode optar também por não utilizar controle de transação. Neste caso, basta não utilizar a anotação @Transactional. Contudo,
caso você a utilize e não defina qual estratégia deseja utilizar, o framework lançará uma exceção lhe avisando sobre isto!
Estratégia JPA
Esta estratégia, que está disponível na extensão demoiselle-jpa, delega o
controle de transações para o javax.persistence.EntityManager da
especificação JPA. Você deve escolher esta estratégia quando você estiver fazendo a persistência
com JPA e utilizando apenas uma base de dados em sua aplicação. Como um EntityManager
acessa apenas uma unidade de persistência, não há como fazer o controle transacional de unidades distintas.
A transação JPA é simples de configurar e não exige nenhum recurso externo à sua aplicação.
Basta definir no arquivo demoiselle.properties a seguinte configuração:
frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JPATransaction
Caso não esteja utilizando o arquétipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependência para a
extensão está indicada corretamente no arquivo POM.XML.
br.gov.frameworkdemoiselle
demoiselle-jpa
compile
]]>
Estratégia JTA
Esta estratégia, também está disponível através de uma extensão: demoiselle-jta e é
responsável por delegar o controle de transação para um container JEE. Com a JTATransaction
é possível incluir várias unidades de persistência de uma mesma aplicação no mesmo contexto transacional.
Isso mesmo, o famoso Two-Phase Commit (2PC).
A estratégia JTA não serve apenas para persistência em banco de dados, serve também para integrar com
tecnologias que façam acesso ao contexto JTA, como é o caso do EJB. Para ativar esta estratégia defina no
arquivo demoiselle.properties a seguinte configuração:
frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JTATransaction
Feito isto, o controle transacional será delegado para a transação acessível via JNDI com o nome
UserTransaction. A estratégia acessa o objeto da seguinte maneira:
Beans.getReference(UserTransaction.class). Portanto, para você utilizar esta estratégia,
você precisa de um container JEE ou de um servidor JTA qualquer.
É preciso também informar no arquivo persistence.xml o endereço da conexão
JTA gerenciada. Veja um exemplo utilizando o servidor de aplicações JBoss-AS6 e com o provider Hibernate (embutido no JBoss-AS) como implementação JPA:
java:jboss/datasources/ExampleDS
]]>
Caso não esteja utilizando o arquétipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependência para a
extensão está indicada corretamente, no arquivo POM.XML.
br.gov.frameworkdemoiselle
demoiselle-jta
compile
]]>
Crie a sua estratégia
Caso nenhuma das estratégias oferecidas sirva para você, crie a sua. Basta escrever uma
classe não-final que implemente a interface Transaction do pacote
br.gov.frameworkdemoiselle.transaction. Anote a classe com
@SessionScoped e @Alternative para que o CDI saiba
que se trata de uma estratégia. É preciso que sua classe não possua construtores explícitos ou
que possua um construtor público sem parâmetros. É possível fazer injeções nesta classe.
Basta agora definir no arquivo demoiselle.properties a sua estratégia:
frameworkdemoiselle.transaction.class=projeto.MegaTransaction