Solução para Gerenciamento de Transações no

Propaganda
PLATAFORMA PINHÃO PARANÁ
Solução para Gerenciamento
de Transações no Framework Pinhão
Abril – 2006
Sumário de Informações do Documento
Tipo do Documento: Definição
Título do Documento: SoluçãoCELEPARpara gerenciamentode Transaçõesno HIBERNATE
Estado do Documento: Elaborado
Responsáveis: José AugustoSoaresPrado
Palavras-Chaves: Hibernate, transações, Plataforma Pinhão
Resumo: Transaçãoé um conceito fundamentalde todo sistemade bancode dados
Número de páginas: 09
Software utilizados:
Versão
Data
Mudanças
1.0
04/2006
Elaboração
SUMÁRIO
INTRODUÇÃO.......................................................................................................................................................4
TRANSAÇÕES ANINHADAS...............................................................................................................................4
PROBLEMAS ENCONTRADOS..........................................................................................................................5
MÉTODOS IMPORTANTES ............................................................................................................................................6
POSSÍVEIS COMPLICAÇÕES JÁ TRATADAS......................................................................................................................7
EXEMPLOS DE UTILIZAÇÃO...........................................................................................................................8
4
INTRODUÇÃO
Transação é um conceito fundamental de todo sistema de banco de dados. O ponto
essencial de uma transação é que vários passos são unidos em um único processo atômico.
Defini-se processo atômico ou bloco de código atomizado como um bloco de código repleto
de procedimentos onde é exigida a condição: ou todos os procedimentos são concluídos com
sucesso ou nenhum deve ser realizado de fato.
A Plataforma Pinhão utiliza o framework HIBERNATE para persistência de objetos e
este usa a linguagem HQL como interface SQL ao desenvolvedor, isto faz com que se
programe sempre a mesma consulta HQL independentemente de qual banco de dados é
utilizado. Além disso, o HIBERNATE trata de maneira transparente as chaves primárias,
estrangeiras e tabelas associativas, abstraindo o acesso aos dados e facilitando uma possível
mudança de fornecedor de banco de dados.
Os patterns DAO e FAÇADE, utilizados pela Plataforma Pinhão Paraná, foram criados
com o intuito de modularizar de maneira organizada as camadas e tarefas dentro do modelo
MVC (Model View Controller) em um sistema. Ambos patterns “trabalham” em conjunto na
camada Model, cada qual com suas atribuições.
Tendo estes conceitos em mente, trataremos dos pontos relevantes em transações e da
solução adotada pela Plataforma Pinhão para melhorar o controle de transações na sua
arquitetura.
TRANSAÇÕES ANINHADAS
Transações aninhadas são transações dentro de transações, ou seja, dentro de um bloco
de SQL atomizado encontra-se outro sub-bloco de código SQL que deve ser atomizado
também, independentemente do bloco pai. Esse recurso é provido por alguns bancos de dados
porém não é suportado pelo HIBERNATE.
PINHÃO- FRAMEWORK- CELEPAR
5
Por exemplo:
BEGIN;
UPDATE .... (1)
BEGIN;
UPDATE .... (2)
COMMIT;
UPDATE .... (3)
ROLLBACK;
Caso o código acima venha a ser passado para um banco de dados sem suporte a
transações aninhadas, a interpretação será um tanto confusa e errada. Este banco de dados
ignorará o segundo BEGIN, pois já existe uma transação aberta. Porém realizará o COMMIT
considerando o primeiro BEGIN.
Ao encontrar o comando ROLLBACK, a ação é desfazer tudo até o ultimo COMMIT, então
será desfeito apenas o UPDATE ... (3).
Essas limitações impossibilitam o uso de transações aninhadas no momento.
PROBLEMAS ENCONTRADOS
Ao utilizar como padrão a abertura de transações nas classes do tipo DAO alguns
problemas de padronização eram encontrados. Pelo fato de nem toda transação se resumir a
um único método da classe DAO, a conexão com o banco, ou sessão no caso do
HIBERNATE, precisa ser passada de alguma forma para o próximo método que irá continuar
a execução da transação. Apesar da solução para esse problema ser simples, isso faz com que
cada desenvolvedor resolva de uma forma diferente, o que ocasiona falta de padronização na
codificação, dificultando a manutenção do código e principalmente incompatibilidades com a
especificação do sistema.
Outro problema levantado acontecia quando uma Façade precisava chamar o método
de outra Façade, onde ambos precisam controlar transações. Neste caso transações aninhadas
seriam abertas, o que já vimos que não é suportado.
PINHÃO- FRAMEWORK- CELEPAR
6
SOLUÇÃO
A solução adotada foi a de não abrir uma sessão (conexão) para cada query que
desejamos fazer, e sim fazer com que uma mesma sessão seja usada para um mesmo request,
isto é, uma mesma Thread. Para tornar isso possível e conciliável com os padrões DAO e
FAÇADE a solução é abrir a transação nas classes do tipo FAÇADE e utilizar os novos
métodos do Framework Pinhão para controle de transações e sessões.
Como foi dito anteriormente quando uma Façade precisar chamar o método de outra
Façade poderíamos ter um problema pois transações aninhadas seriam abertas devido ao fato
de estar especificado que cada Façade deve ter a sua transação. Para evitar que sejam
realmente abertas transações aninhadas, o Framework Pinhão se encarregará de ignorar essa
nova abertura de transação.
Métodos Importantes
Tal controle de transações não precisará ser preocupação do desenvolvedor desde que
este use a chamada das transações e sessões através dos métodos estáticos currentSession e/ou
currentTransaction da classe HibernateUtil do Framework Pinhão.
O método
currentTransaction deve ser chamado nas classes do tipo FAÇADE, quando necessitarem de
controlar transações, enquanto o método currentSession deve ser chamado em todas as classes
do tipo DAO. Estes métodos abrem transação e sessão, respectivamente, e os associam a
Thread da requisição.
Para fechar a transação e sessão o desenvolvedor deve utilizar os métodos
HibernateUtil.commitTransaction ou o HibernateUtil.rollbackTransaction. Todas as classes
DAO deve chamar o método HibernateUtil.closeSession, este método só fechará realmente a
sessão (conexão) se não estiver dentro de uma transação.
Seguindo a mesma lógica de abertura, a transação deve ser fechada na FAÇADE e a
sessão “fechada” na DAO. Isso pode parecer um pouco estranho a primeira vista, mas o fato é
que utilizando esses métodos, a sessão não será de fato fechada caso ainda exista uma
PINHÃO- FRAMEWORK- CELEPAR
7
transação aberta. Porém é importante a utilização desde padrão pois facilitará a manutenção e
garantirá um melhor reaproveitamento de código.
Para entender melhor o uso destes métodos tão importantes verifique os exemplos
disponíveis neste documento.
A Plataforma Pinhão fará um controle transacional e ignorará as transações aninhadas
que virão a ser chamadas nesses casos, passando para o HIBERNATE apenas a transação
principal, ou seja, a primeira que foi aberta e o último fechamento (seja COMMIT ou
ROLLBACK).
Possíveis Complicações já Tratadas
Existem então, quatro maneiras diferentes de uma transação aninha ser formada:
BEGIN
BEGIN
BEGIN
BEGIN
BEGIN
BEGIN
BEGIN
BEGIN
COMMIT
ROLLBACK
COMMIT
ROLLBACK
COMMIT
COMMIT
ROLLBACK
ROLLBACK
Dentre essas quatro maneiras, apenas a segunda maneira apresenta um problema em
potencial. Caso aconteça um ROLLBACK na transação interna, o componente HibernateUtil
do Framework Pinhão guardará essa informação e fará um ROLLBACK na transação
principal, mesmo que ao final seja chamado um COMMIT. É importante fazer um bom
controle de exceções no caso de um ROLLBACK ser acionado dentro de uma transação
interna. Uma boa prática neste caso é que o desenvolvedor sempre lance uma exceção logo
após o ROLLBACK, pois caso essa situação ocorra a FAÇADE, externa que gerou a primeira
transação, poderá capturar essa exceção e fazer o devido tratamento.
PINHÃO- FRAMEWORK- CELEPAR
8
EXEMPLOS DE UTILIZAÇÃO
Seguem abaixo, exemplos de métodos de FAÇADE e de DAO utilizando o
componente HibernateUtil do Framework Pinhão para controlar transação e sessão.
Exemplo de método da FAÇADE, iniciando a transação e chamando um método da classe
DAO para salvar um aluno.
public String salvarAluno(Aluno aluno) throws ApplicationException, Exception {
String retornoNatural = null;
DAOFactory hibernateFactory = DAOFactory.getDAOFactory(DAOFactory.HIBERNATE);
try {
HibernateUtil.currentTransaction(); //Abre sessão e transação
AlunoDAO alunoDao = hibernateFactory.getAlunoDAO();
alunoDao.salvarAluno(aluno);
retornoNatural = alunoDao.consultaNatural();
HibernateUtil.commitTransaction(); //Fecha sessão e transação
} catch (ApplicationException appEx) {
HibernateUtil.rollbackTransaction();
throw appEx;
} catch (Exception ex) {
HibernateUtil.rollbackTransaction();
throw new ApplicationException("mensagem.erro.matricula.servico.salvarAluno", ex,
ApplicationException.ICON_ERRO);
}
return retornoNatural;
}
Exemplo de método de busca em uma DAO, tenha em mente que é de essencial importância o
tratamento das exceção:
public Aluno buscarAlunoPorPK(Integer codAluno) throws ApplicationException, Exception {
Aluno aluno = null;
try {
Session session = HibernateUtil.currentSession();
aluno = (Aluno) session.load(Aluno.class, codAluno);
logAuditoria.info("BUSCA DE ALUNO: Aluno "+ aluno.getNomeAluno() +" consultado por
Xxxxxx");
PINHÃO- FRAMEWORK- CELEPAR
9
} catch (HibernateException he) {
throw new ApplicationException("mensagem.erro.matricula.listaDeAlunos", he);
} catch (Exception e) {
throw e;
} finally {
HibernateUtil.closeSession();
}
return aluno;
}
CONCLUSÃO
Apesar de possíveis limitações da arquitetura, a Plataforma Pinhão está desenvolvendo
tecnologia para tornar o desenvolvimento de software mais organizado e robusto,
conseqüentemente agilizando o processo de desenvolvimento. A utilização dos novos
métodos da classe HibernateUtil facilitará o gerenciamento das transações HIBERNATE e
manterá a modularidade proposta com relação a camada de banco de dados.
PINHÃO- FRAMEWORK- CELEPAR
Download