quarta-feira, 12 de novembro de 2008

Gerenciamento de Transações com JTA

Segue abaixo algumas considerações acerca da API JTA e de como EJB3 suporta transações declarativamente.

Normalmente as transações em aplicações são controladas em nível de métodos de negócio. Para se declarar que se está sendo utilizada alguma transação deve se utilizar a anotação @TransactionAttribute.

Por padrão a transação utiliza a estratégia REQUIRED, que significa que se o método do serviço não possuir alguma transação, uma será criada, e se já possuir uma transação esta será aproveitada. Esta é a estratégia que deve ser utilizada na maior parte dos casos uma vez que é bem lógica.

O que esta estratégia quer dizer resumidamente? Quando você estiver em um contexto de transação e caso ocorra alguma exceção do tipo Runtime ou exceção com a anotação @ApplicationException(rollback=true), deve ser dado o rollback na base de dados. Com esta estratégia padrão sempre será dado o rollback da transação mais externa, o que na maioria dos casos faz todo sentido.

Outras estratégias são:
  • SUPPORTS - Não cria nenhuma transação, mas se já existir alguma ela será utilizada.
  • MANDATORY - Requer que quem chamou o método tenha criado uma transação.
  • NEVER - Proíbe que quem chamou o método tenha iniciado uma transação.
  • REQUIRESNEW - Sempre começa uma nova transação, suspendendo a antiga existente.
  • NOTSUPPORTED - Suspende qualquer transação ativa.
Como padrão, pode-se anotar toda a classe com a anotação @TransactionAttribute, o que determina que todos os métodos da classe utilizam transação e com a estratégia REQUIRED. Caso exista algum método que deva usar outra estratégia basta sobrescrever a estratégia usando acima do método alguma das anotações abaixo:
  • @TransactionAttribute(TransactionAttributeType.NEVER)
  • @TransactionAttribute(TransactionAttributeType.MANDATORY)
  • @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
  • @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  • @TransactionAttribute(TransactionAttributeType.SUPPORTS)
Agora é definir para os métodos qual o melhor tipo de estratégia de transação e sobreescrever.É isto aí pessoal. Qualquer problema me avisem.

4 comentários:

Livro Android disse...

Samuel,

é necessário anotar a classe com @TransactionAttribute para fazer com que todos os métodos tenham transação?

já não existe um default? para nem precisar anotar?

Ricardo

Samuel Martins Delfim disse...

Não existiria um default não. Na teoria vc tem algumas opções. Uma das opções é vc utilizar a anotação acima da classe, outra seria vc colocar a anotação em cima de cada método. Outra opção é utilizar o descritor de implantação EJB ou realizar o controle de transação explicitamente com código Java. Acho que a melhor opção é colocar a anotação em cima de toda a classe fazendo com que funcione para todos os métodos. Qualquer problema me avise...

Paulo disse...

Opa, Samuel,
Se me permitir, gostaria de citar um trecho do livro Enterprise JavaBeans 3.0 de Bill Burke e Richard Monson, pag 265. "Se você não especificar nenhuma @TransactionAttribute e não houver um descritor de implantação XML, o atributo de transação padrão será REQUIRED."
Espero ter ajudado.
Grato.
Paulo

Samuel Martins Delfim disse...

Olá Paulo,

Você está redondamente certo. Ricardo, desculpe a falha ao responder. O Default como disse pelo Paulo é Required.

[]s,

Samuel