Arquitetura transacional

Bom dia caros amigos do GUJ, estou desenvolvendo um sistema JEE e o padrão de acesso ao banco de dados é tal que o meu BO pede à fábrica de conexões ( uso o pattern abstract factory ) o DAO correspondente, este conecta no banco, realiza a operação em apenas uma tabela e fecha a conexão, detalhe, autocomit=true. Precisei atualizar duas tabelas simultâneamente, logo surgiu um contexto em que se a atualização de uma tabela falhar, a operação que consiste em manipular as 2 tabelas deve falhar. No meu caso tenho métodos separados em cada DAO, para atualizar a tabela, não conseguí ver uma forma de compartilhar a mesma conexão pelo padrão operacional que estou seguindo para operar o bd e também não sei se um singleton resolveria meu problema. Alguém poderia me ajudar? Um abraço e obrigado pela atenção…

Será que a única forma seria manipular as duas tabelas dentro de um método do mesmo DAO, acho que isso fere princípios arquiteturais, um DAO manipulando tabelas que deveriam ser acessadas por outro. Estou em dúvidas…

Amigos, olha só, eu tenho uma classe GenericDAO, pai de todos os DAO’s. Eu consigo informar pra cada DAO se ele está ou não no contexto de operação que envolve mais de um DAO e exige controle transacional. Eu pensei que se colocasse de alguma forma um singleton que retorna uma conexão que provavelmente estaria aberta todo o tempo em que a aplicação esteja publicada, poderia então usar esta conexão para realizar a transação envolvendo os dois DAO’s. Num sei se seria uma boa opção.

Olá Kappa,

A especificação JEE possui o controle transacional que são implementados pelos servidores de aplicação(EJB-centric).

Você pode dar uma olhada também no springframework.

Basicamente, você terá uma classe para implementar a regra de negócios(Nesse ponto o controle transacional é feito) e suas DAOS apenas farão a comunicação com o SGBD.

Daí, imagine algo do tipo:


public class Matricula{

@Transactional // Aqui está a "mágica"
public void matricular(Aluno a, Disciplina d){
   if( a.getId() == null ){
      dao.save(a);
   }
  
   DisciplinaAluno da = new DisciplinaAluno(a,d);
   dao.save(da); // suponha que aqui lance uma exceção. Com a configuração correta, o rollback será feito, portanto, Aluno e DisciplinaAluno não serão salvos.

}
}

Espero ter dado uma clareada.
Até mais.

Gostei da sugestão, na altura do desenvolvimento talvez eu precisaria de bastante refactory para adaptar o uso do Spring Framework, porém é uma ótima sugestão.
Se alguém tiver outras sugestões sem a utilização de um framework… abraço a todos e obrigado pela resposta fabio…

Beleza Kappa,

Se der pra fazer o refactory vai ser legal.
=)

Uma vez eu trabalhei em um projeto que necessitava de um controle transacional bem específico e tudo era feito em memória(cache). Neste projeto não utilizamos Spring mas sim uma implementação nossa para fazer o controle. Funcionou bem, mas ficou bem complexa e demandou muito tempo.

Abraço.

Fabio, estou quase criando um método estático de conexão e passando ele como parâmetro numa sobrecarga do construtor de cada BO envolvido, ae antes de tudo coloco o auto commit dela como false mas vou ter de modificar meus métodos nos DAO’s para não fechar a conexão no finally, na verdade eu a fecho só depois de toda a transação acontecer. Talves eu fecharia no próprio finalize, ( public void finalize()…) desta classe. O que acha disso?.. Só que meu MBean(estou usando JSF2) ficaria meio poluído, mas talvez vale ápena.

Mas onde você faria o rollback ou commit?

A forma que eu mais me lembro de controlar a transação sem nenhum “facilitador/framework” era usar uma variável contadora para identificar se no final era commit ou rollback que deveria ser feito.

Assim:

int result = 0;
try{
   session.save(d)
}catch(Exception e){
 result = 1;
}
return result;

Daí, para cada método chamado, você soma o resultado em uma variável. No final das contas se tiver igual a zero, você “comita”, se não você “rollbeca”… eheh…

Eu acho que vc vai ser mais feliz utilizando EJB ou springframework.

=)

Pois é, eu teria GenericBO e GenericDAO que participariam da transação para dar os controles transacionais, BEGIN, ROLLBACK no cathc da exception e COMMIT se a operação como um todo finalizar bem. O Generic BO também receberia a mesma conexão dos demais BO’s envolvidos e passaria para o GenericDAO que se encarregaria de tais comandos transacionais.

Estática você não poderia deixar pois várias requisições são feitas né.

Você poderia gerenciar a vida da sua conexão com espoco de requisição, daí você poderia compartilhá-la entre seus BO’s e DAO’s durante toda uma requisição.

Você está utilizando JDBC?

Sim, uso JDBC…

O que eu faria se fosse estatica seria, criava uma referência pra ela no MBean e passaria essa referência para todos os BO’s envolvidos sendo que as requisições à conexão seriam sequênciais. Mesmo assim você acha q existe algum problema?

É…

Eu não faria do jeito que você tá querendo, mas quem sabe do projeto aí é você né!? =)

Tenta bolar uma coisa bacana com tudo isso aí que conversamos.

Até.