Re: Gerenciamento de transações. Porque não no DAO?

Se você tá chamando “commit()” no Dao, qual a diferença de chamar “commit()” no banco? O que foi que você abstraiu fazendo isso? A lógica do banco de dados está vazando pro código cliente, que nem deveria saber que tem um banco relacional “do outro lado do espelho”.

Se você quer algo concreto, é só ver tudo o que já foi falado sobre ThreadLocal e filtros nos últimos dias, ou dar uma olhada no controle de transações do Spring:

http://static.springframework.org/spring/docs/1.2.x/reference/index.html

Usa o Spring ou então cria interceptors pra fazer do mesmo jeito que o filtro faria em uma aplicação web, usando AOP é barbada.

Não é correto colocar o controle dentro do seu DAO, mesmo pq, se você precisar de uma transação que envolva mais de um DAO, vc tá ferrado.

Eu fiz algo assim:

Transaction t = TransactionManager.beginTransaction(); try { dao1.save( x ); z =dao99.select( 1 ); dao666.update( z ); dao12345.delete( www ); t.commit(); } catch( Exception e ) { t.rollback(); } finally { t.end(); }

Internamente usei ThreadLocal. Meus DAOs pegam a conexão da transação que é compartilhada por eles, via ThreadLocal. Caso não exista uma transação, ele pega um conexão default do DAO.

A conexão retornada pela Transaction é uma casca sobre a Connection original, pois eu desativei coisas como commit(), rollback() e close(), delegando esta função para a Transaction. Por isso é obrigatório chamar o t.end().

O código cliente tem que inicializar as transações Daniel? Não seria melhor que isso fosse feito externamente não? Usando interceptors?

O controle saiu de dentro do DAO mas foi parar no código que usa diretamente os DAOs, não parece melhorar muita coisa não.

O que você sugere, numa aplicação web, por exemplo, é que toda a ação do action, em um request, é uma transação, correto?

Ao meu ver isso prende demais a gente. Posso ter mais de uma transação ocorrendo no meu negócio e quero poder ter este controle.

Pelo menos meu código de negócio sabe onde começa e termina sua transação. O que fiz foi simplesmente achar uma forma de desacoplar e abstrair o uso de transação para um modelo mais genérico do que acessar recursos indevidamente, além de ser uma forma mais elegante de controle.

Como em EJB você pode criar um método que atenda a uma nova transação, mas como não uso EJB, fiz usando essa camada de controle.

[quote=danieldestro]O que você sugere, numa aplicação web, por exemplo, é que toda a ação do action, em um request, é uma transação, correto?

Ao meu ver isso prende demais a gente. Posso ter mais de uma transação ocorrendo no meu negócio e quero poder ter este controle.
[/quote]

Ora, o Spring dá esse controle sem deixar a transação aparecer pro código cliente :mrgreen:

Mas num sistema onde, nos recursos tecnologicos, não pode aplicar coisas como EJB, Spring e SuperSoluçãoInovadora ™, a melhor solução foi aquela.

Nesse caso num tem muita escolha né :lol:

Mas ainda existem os iinterceptadores com AOP né, ninguém vai reclamar de um bytecode a mais (num vai nem perceber) :mrgreen:

heheehe… vc não sabe metada da história lá.
por isso já estou de saco cheio.
em 6 dias pego 40 dias de férias.

[quote=danieldestro]heheehe… vc não sabe metada da história lá.
por isso já estou de saco cheio.
em 6 dias pego 40 dias de férias.[/quote]

Bem que eu queria ficar de saco cheio de férias :mrgreen:

Quer trocar por dois cursos superiores e um estágio miserável? :lol:

2 faculs + estágio? Você tá fudido. que estuda?

Jornalismo e Desenvolvimento de Software.

O estágio pelo menos eu resolvo em casa mesmo (eles nem iam ter PC pra rodar o Eclipse mesmo…).

Mas pelo menos tá mais perto do que longe, ano que vem eu termino as duas :mrgreen:

O povo por aí proíbe de usar frameworks é?

Pelo que eu entendí você não trabalha, né?

Então, depende da empresa/gestor, é complicado. Se eles fecham um escopo de tecnologia, é bem difícil sair daquilo e usar outras coisas. Ainda mais em grandes empresas com grandes projetos. Eles têm de gerenciar os detalhes, e é aí que às vezes podem limitar nossa capacidade e inovação.

Lá eu consigo usar muita coisa nova. Eu, quando posso, fica colocando algo pra ajudar, mas não fico inventando muito fora daquilo, ainda mais pq usamos um framework in-house, que fede.

Como nunca usei AOP, não fico tentando inventar e, de repente, perder muito tempo aprendendo algo que pode fadar ao fracasso.

Nops, só o estágio e um projeto de pesquisa mesmo.

Vixe, framework próprio é uma coisa complicada. Uns amigos fizeram um framework MVC pra o estágio deles mas no fim a coisa ficou muito complicada e quando eles saíram a galera que entrou “dançou beleza”, porque ficou amarrada a uma coisa não tão bem feita (agente ainda é estudante né :lol: ) e que só tem manutenção lá dentro.

Eu não acho que seja uma boa investir numa coisa dessas se for absolutamente necessário e não houver nenhuma outra opção decente que possa ser usada ou adaptada.

Acho que isso é até uma vantagem do meu estágio, o povo só quer a coisa pronta, não interessa como. Comecei com Struts/Hibernate/JSP/Velocity, agora tô terminando uma migração pro Hibernate 3, colocando o Spring junto com o Struts e eu espero anter de terminar migrar tudo pro Spring MVC. Lá eu to botando a teoria na prática e tá valendo muito a pena, esse negócio das transações “externas” eu botei em prática lá, são as minhas cobaias :mrgreen:

[quote=danieldestro]
Como nunca usei AOP, não fico tentando inventar e, de repente, perder muito tempo aprendendo algo que pode fadar ao fracasso.[/quote]

Sei não velho, AOP não é a resolução pra todos os problemas, mas esse tipo de “interceptação” é uma das especialidades, dá uma olhada no AspectJ, pode ser que te ajude numa outra coisa que não tem nada haver com isso :smiley:

Esse FMK in-house foi feito em 99 ou 2000. Cara, é uma grande lástima da minha vida. O cara que o fez, simplementes fez uma versão para quase cada um dos projetos existentes. Isso que alguns migram de plataforma e temos que trocar o FMK. É um Deus nos acuda. Um saco!

Por isso já tô de saco cheio. Quero inovar, por coisas novas, inventar, e não me limitar. Para isso acho que preciso mesmo pôr em prática a minha consultoria e projetos próprios. Logo, logo!

Sobre o AOP, eu tô ligado, mas qdo se tem prazos e limitações, inovar não é a “melhor” solução.

[quote=Maurício Linhares]O código cliente tem que inicializar as transações Daniel? Não seria melhor que isso fosse feito externamente não? Usando interceptors?

O controle saiu de dentro do DAO mas foi parar no código que usa diretamente os DAOs, não parece melhorar muita coisa não.[/quote]

Olá, desculpe por interromper a conversa de vocês sobre fmk, empresas e outras coisitas… mas queria aproveitar a colocação acima do Maurício para tirar uma dúvida!

Bom, a questão é a seguinte.

Se eu ficar amarrando o início da transação e o término dela em um interceptor, filtro, ou seja lá o que for acho super bacana. No entanto, e quando inicio uma transação que só irá fazer um select all?? Para isso eu não precisaria de uma transação!

Como vcs lidam com isso? Vcs iniciam um transação assim mesmo, ou em caso de consultas vcs não iniciam a transação?

Se Vocês não iniciam a transação, então como vcs fazer para controlar isso?

Abraços!
Thiago

[quote=Thiago Senna] Se eu ficar amarrando o início da transação e o término dela em um interceptor, filtro, ou seja lá o que for acho super bacana. No entanto, e quando inicio uma transação que só irá fazer um select all?? Para isso eu não precisaria de uma transação!

Como vcs lidam com isso? Vcs iniciam um transação assim mesmo, ou em caso de consultas vcs não iniciam a transação? [/quote]

Eu sempre inicio uma transação, mesmo que seja pra um select.

Por isso não sou muito fã desta abordagem. Perda de recursos.

Por isso não sou muito fã desta abordagem. Perda de recursos.[/quote]

Será que faz diferença?

Nunca medi isso… mas é até uma boa não fazer em selects.

No fim, num tenho como saber, é o Spring que faz pra mim :mrgreen:

Gerenciar as transações fora dos DAOs permite você usar mais de um DAO sem muita dor de cabeça.

E para evitar ficar repetindo o código de gerenciamento de transações faço o mesmo que com statements e resultsets, uso um Command.

Crio um TransactionalCommand e mando executar ele dentro de um contexto transacional ou não. Veja que é possivel inclusive proteger de ter uma action que deveria ser read-only modificando a base. Fazendo wrapping da Connection como o Destro sugeriu.