MVC com Controle de Transação

Bom dia senhores

Estou no processo de desenvolvimento de um sistema Comercial em Java Desktop e me surgiu uma dúvida, como fazer o controle de transação quando envolver mais de um DAO?

A minha ideia é construir um padrão onde o meu DAO (independente de se for com jdbc puro ou com jpa) receba o objeto de controle, grave, altere, exclua mas sem saber se está ou não dentro de uma transação. E teria um Controller que saberia quais DAO’s ele precisa e ele controlaria essa transação.

Eu não sei como fazer o controle, pois acredito que o Controller não deveria conhecer o método de gravação (jdbc / jpa) e somente ter uma maneira de iniciar a transação, fazer o commit em caso de sucesso e fazer rollback se houver erro.

Alguém tem uma ideia para me ajudar?

Penso que ele fará o commit quando não houver exceção e, quando houver, faz o rollback, não?

Não é em relação ao processo e sim a junção dos objetos, pois o controller não deveria conhecer o Connection por exemplo, somente o DAO.

Camarada, você está viajando. O controller não vai conhecer isso, a não ser que você não saiba o que faz.
O controller vai saber que o DAO possui um método para executar o que deve ser feito (INSERT, UPDATE ou DELETE) e um método para confirmar o que foi feito (commit) ou desfazer (rollback). É tua responsabilidade isolar o que acontece dentro destes métodos.

O que você não entendeu é que um controller pode conhecer 1 ou mais daos, quando é somente um dao é moleza, a questão é quando é necessário gravar em dois daos diferentes e manter o controle transacional.

Amigão tem um módulo do Spring Framework que simplifica o uso da JPA:

  • Spring Data JPA

E um módulo de controle transacional:

  • Spring Transaction

Então para persistência vc poderia pensar em usar esses módulos do Spring Framework.

Bom você teria algum exemplo do uso do Spring?

tebosoftware tem esse projeto de exemplo da YaW Tecnologia:

http://www.yaw.com.br/open/projetos/swing-spring-jpa-crud/

Recomendo utilizar o Spring também.
Caso não queira pode dar uma olhada em AOP e criar seu
próprio gerenciamento de transação.
Utilizando um aspecto que trabalhe em cima de métodos com uma determinada anotação
e abrindo e fechando transactions quando necessário.

Obrigado senhores

vou olhar este projeto e também dar uma olhada em AOP.

Na verdade o que está te faltando é uma camada de serviços, que é onde se encontram as regras de negócio de fato. Os DAOs compõe a camada de persistência, ou seja, eles servem apenas de ponte entre as regras de negócio e o seu mecanismo de persisência. E de fato, DAO’s não são transacionais, justamente porque uma operação de negócio pode envolver mais de um DAO.

Em um arquitetura JEE, esse objeto é chamado de Session Facade, implementado tipicamente como um EJB. Mesmo que sua arquitetura não seja JEE, a idéia é basicamente a mesma. Um objeto que oferece diversos “serviços”. Um serviço nada mais é do que uma regra de neǵocio, um método que representa uma transação completa. Por exemplo:

class CompraService{
   public void finalizarCompra(CarrinhoCompras carrinho, FormaPagamento formaPgto){
      //dá baixa no estoque
      //dá entrada no financeiro
      //emite nota fiscal 
   }

   public void cancelarCompra(NumeroNota numero){
     //...
   }
}

Mantendo essa camada, fica mais simples delinear onde devem acontecer as transações. Você pode até fazer transações manuais que funciona, mas de fato, usar uma API de AOP deixa o código mais elegante.

No meu caso o Controller é a regra de negocio sim. E nesse sentido ele teria que saber como buscar a conexão e injetar nos daos para que ele controlasse a transação?

Então o seu Controller está errado. Tem muitas discussões sobre isso no GUJ, vale a pena você dar uma olhada.

E a resposta para sua pergunta é sim. Se você colocou regras de negócio no controller então ele vai ter que buscar conexões e controlar transações também.

Como assim errado?
O meu controler controla coisas como o bean ativo, a pesquisa, exclusao, listas pra combo etc.
Isso eerrado?

Uma outra coisa, AOP com Netbeans funciona?

Você pode usar uma implementação de AOP (como o AspectJ , que é a mais popular e talvez a mais completa) para
fazer o que precisa. Dá uma olhada nesse link.
O legal é que o AspectJ te fornece tanto uma DSL pra trabalhar com aspectos como também uma forma
de criação de aspectos com classes Java mesmo, através do uso de annotations.

Isso é errado. As regras estarem no seu Controller. Deveriam estar nas suas entidades e/ou camadas de Serviço.

Esse link que você me passou e não funciona em Netbeans 7.x, é limitada até a 3.x. E eu vi num fórum que o do Spring é melhor, vou dar uma olhada e tentar entender.

Isso é errado. As regras estarem no seu Controller. Deveriam estar nas suas entidades e/ou camadas de Serviço.[/quote]
++

[quote=tebosoftware]Como assim errado?
O meu controler controla coisas como o bean ativo, a pesquisa, exclusao, listas pra combo etc.
Isso eerrado?[/quote]

Antes de mais nada, me desculpe. Preciso tomar mais cuidado antes de dizer que algo está “errado” …

Bom, pela sua descrição, a sua solução se parece mais com um MVP (Model View Presenter) do que um MVC propriamente dito. O MVP é um padrão muito interessante também, eu acho que a compreensão dele mais simples que a do MVC.

Me parece também que você fez uma pequena confusão. Regra de negócio ou lógica de negócio diz respeito somente ao domínio da aplicação e relacionamento entre entidades; Ela fica um nível acima da persistência mas não toma conhecimento sobre como a interface é controlada; Em um MVC, a própria View deve controlar seu estado (me corrijam se eu estiver errado), pois o Controller deveria apenas encaminhar requisições para o Model e devolver as respostas para a View. Já no padrão MVP o Presenter é quem mantem o estado da View, além de fazer a ponte entre Model e View, de forma que o Presenter chama diretamente as interfaces de serviço expostas pelo Model.

Mas enfim, como eu acho que se apegar demais a nomes pode ser improdutivo (não quero que você pense que tudo o que você fez está “errado”), vou só reforçar a minha sugestão:

1 - criar classes de serviços para conter regras de negócios. Serviços seriam métodos que representam 1 regra de negócio completa, ou seja, exatamente 1 transação. A transação deve começar no início do método e terminar no fim do método, fazendo rollback caso tenha alguma exceção. Você poderia receber a conexão via injeção de dependências ou então instanciar diretamente uma fábrica de conexões.

2 - eu avaliaria se as suas classes controller não estão acumulando responsabilidades. Talvez seja esse o caso. Assim, seus controladores ao invés de encaminhar chamadas a DAOs, encaminharia chamadas para serviços. O que eu defendo é que controllers ou presenters não devem preocupar-se com transações.

Espero que seja útil;