Padrões de Transações Java com Spring Framework

Postado em Atualizado em

Uma transação é uma seqüência de ações que são tratadas como uma única unidade de trabalho. Essas ações devem ser completas ou não terem nenhum efeito. O gerenciamento de transações é uma parte importante no desenvolvimento de soluções corporativas, sendo que é que deve garantir a integridade e consistência dos dados  nas operações. Existem 2 tipos de transações:  Locais e Globais.

Transações locais versus globais

As transações locais são específicas para um único recurso transacional, enquanto as transações globais podem abrangem vários recursos transacionais distribuídos.

O gerenciamento local de transações pode ser útil em um ambiente de computação centralizado, onde os componentes e recursos do aplicativo estão localizados em um único lugar, e o gerenciamento de transações envolve apenas um gerenciador de dados local executado em uma única máquina. As transações locais são as mais fáceis de implementar.

O gerenciamento de transações globais é necessário em um ambiente de computação distribuído, onde todos os recursos são distribuídos em vários sistemas. Nesse caso, o gerenciamento de transações precisa ser feito tanto a nível local como global. Uma transação distribuída é executada em vários sistemas, e sua execução requer coordenação entre o sistema global de gerenciamento de transações e todos os gerenciadores de dados locais de todos os sistemas envolvidos.

Spring Framework

Spring Framework fornece toda infraestrutura necessária para se gerenciar transações locais, globais e variações das mesmas. Ou seja, você não precisa perder seu tempo fazendo isso, já esta pronto e disponível através de vários projetos do ecossistema spring. É muito importante que um arquiteto de software Java conheça essas opções e tipos de transações, tendo base para a tomada de decisão diária aí em seus projetos. Segue abaixo um resumo básico das opções em formato de patterns do qual eu venho usando no meu dia dia:

1)Single Transaction RDBMS Pattern

Usado para gerenciar transação local com um único banco de dados, usando um único tipo de serviço e uma simples tecnologia.
Exemplo: solução java persiste dados no MySQL usando uma unica tecnologia JPA.
Spring fornece 3 produtos para resolver tal necessidade:

  1. Spring oferece gerenciador de transação automático para banco de dados relacional: TransactionManager.
  2. Spring oferece gerenciador de transação para as framework e tecnologias de persistência mais usada da plataforma Java: JDBC, IBatis, Hibernate e JPA.
  3. Spring oferece AOP baseado em anotação para gerenciando de demarcação de transação automática e recursiva: @Transaction.

2)Shared Transaction RDBMS Pattern

Usado para gerenciar transação local com um único recurso, usando múltiplos tipos de serviço e tecnologias.
Exemplo: solução java persiste dados no MySQL usando diferentes tecnologias: JDBC e JPA.
Spring fornece 1 produto para resolver tal necessidade:

  • Spring oferece um gerenciador de transação automático que une em um unica transação múltiplos tipos de tecnologias.

Exemplo: Configurar JpaTransactionManager + HibernateJpaDialect compartilhas as conexões e transações da solução usando tecnologia JPA com JDBC simultaneamente.

3)Single Transaction RDBMS + MOM Pattern

Usado para gerenciar transação local com um banco de dados e um MOM, no qual os dados da solução e a persistência das mensagens do MOM fiquem dentro do mesmo banco de dados. Para que isso funcione, o provedor de MOM precisa ter uma arquitetura flexível para fazer a configuração da estratégia de persistência de mensagens dentro do mesmo banco de dados da solução.
Exemplo: solução java persiste dados no MySQL e usa ActiveQQ persistindo as filas/tópicos dentro da mesa base.
Spring fornece 1 produto para resolver tal necessidade:

  • Spring oferece recurso para setar o mesmo gerenciador de transação da camada de persistência da solução sincronizada com persistência das mensagens enviadas para o MOM.

Exemplo: Configurar org.apache.activemq.store.jdbc.JDBCPersistenceAdapter + com.springsource.open.jms.JmsTransactionAwareDataSourceProxy, faz com que as transações da camada da solução fiquem integradas com as persistencia das filas/tópicos do Apache ActiveMQ.

4)Multiples Transations XA/2PC Pattern:

Usado para coordenar um única transação global de múltiplos recursos diferentes como SGBD’s e MOM’s, remotos e distribuídos. Todos independentes e de marcas diferentes. Para que isso funcione, todos os recursos devem aderir ao contrato do proto copo de transação de banco de dados XA/2PC e a especificação java JTA.
Exemplo: solução java persiste dados em um Oracle, em um SQLServer e usa ActiveMQ persistindo as filas/tópicos em banco de dados MySql.
Spring fornece 3 produtos para resolver tal necessidade:

  1. Spring oferece o contrato do gerenciador de transação automático baseado em JTA: JtaTransactionManager, mas não oferece implementação desse serviço.
  2. Alguns provedores de JTA já tem implementações que pode ser usadas no Spring. Exemplos: Atomikos e Bitronix.
  3. Spring oferece um componente integrador com container FULL JEE. O próprio container possui implementação própria de XA/2PC e JTA, fazendo com que o spring use esse implementação para gerenciar as transações de seus beans.

Prós:
– 100% de garantia de confiabilidade de transação ACID.
– Garante 100% rooback e commit, mesmo com falhas de infraestrutura: travamento, crash, falta de energia, falha de HD, queda de rede e etc
– Usa protocolo XA/2PC e chamadas remotas para garantir a transação.

Contras:
– Todos os recursos precisam implementar XA/2PC.
– Todos os recursos precisam estar configurados para rodar com XA/2PC
– Adquirir um provedor de JTA para XA/2PC open ou paga.
– Reduz tempo de resposta com I/O no protocolo 2PC, sendo que a transação é gerenciada de forma distribuída.
– Reduz escalabilidade com I/O no protocolo 2PC, sendo que a transação é gerenciada de forma distribuída

5)Multiples Transations NON XA/2PC Pattern (Best Efforts 1PC):

Usado para coordenar um única transação local múltiplos recursos diferentes como SGBD’s e MOM’s, remotos e distribuídos. Todos independentes e de marcas diferentes. Use essa opção quando por algum motivo, não seja possível utilizar protocolo XA/2PC.
Exemplo: solução java persiste dados em um Oracle, em um SQLServer e por alguma motivo não é possível configurar e usar XA/2PC.

  • Spring fornece uma implementação de um gerenciador de transação chamado de ChainedTransactionManager que implementa esse padrão.

Prós:
– Não usa protocolo XA/2PC.
– É um pattern que “emula” um suposto XA/2PC.
– Melhora no tempo de resposta com menos I/O, uma vez que não existe XA/2PC e nem transação distribuída.
– Melhora na escalabilidade com menos I/O, uma vez que não existe XA/2PC e nem transação distribuída.

Contras:
– Não garante 100% de confiabilidade de transação ACID. Nessa opção, os envolvidos deve ficar ciente desse fato.
– Inconsistências acontecem em casos de falhas de infraestrutura: travamento, crash, falta de energia, falha de HD, queda de rede e etc, dependendo da sequencia do determinado recurso, pode gerar inconsistências, causando comit em 1 recurso e rooback em outro.

Observação:
– As falhas podem ser minimizadas a quase 0%, em caso em que customização adequada na sequencia da configuração da orquestração das transações e investimento melhor de intra que minime falhar infraestruturais nos recursos envolvidos.
– Em certos casos, algumas empresas abrem mão do protocolo XA/2px e aderem a essa estratégia, afirmando que mesmo em casos raros de falhas, o custo da falha seria bem menor que bancar a implementação total do XA/2px.
– Em certos casos, algumas empresas abrem mão do protocolo XA/2px e aderem a essa estratégia, afirmando que é mais barato implementar algum mecanismos dentro da própria solução para identificar e contornar as possíveis inconsistências que bancar a implementação total do XA/2px.

“Este é o dia da vitória de Deus, o SENHOR; que seja para nós um dia de felicidade e alegria!” Salmos 118:24

Anúncios