Stringpath=req.getServletPath();path=path.substring(1,path.indexOf("."));StringactionClass=actions.getProperty(path);if(actionClass==null){thrownewServletException("Url não encontrada. Verifique o endereço digitado");}try{Actionaction=(Action)Class.forName(actionClass).newInstance();action.setRequest(req);action.setResponse(res);action.runAction();}catch(Exceptione){thrownewServletException(e);}
Estou com dúvida em como usar a conexão/transação que é aberta na Action Abstrata no meu DAO… para que ao final seja feito o commit() ou rollback() em caso de erro…do jeito que esta agora… o DAO pega outra conexão no pool…
Primeiro, mude a estrutura e coloque todas as conexões passando pelo DAO.
Depois, crie os métodos que precisa para cada ação com o banco de dados, no DAO.
Isso resolve os problemas que você tem.
P
picklesdog70
Vc diz criar um atributo Connection no DAO?
D
drsmachado
Sim.
Até onde entendo, DAO é a camada que irá conversar com a base de dados. As demais acessam o DAO e todo o processo que dependa da persistência é abstraído a partir daí.
P
picklesdog70
Fiquei com uma dúvida…se eu abrir a Conexão no DAO… fazer o INSERT…commit se der certo e rollback se der erro… caso esse insert dependa de outro insert… pode ser q parte das informações sejam salvas e outras não ne… pq cada DAO terá sua transação… ou não?
Sim, pode incorrer neste erro novamente.
A questão é que você precisa analisar a tua necessidade e fazer opções pelo que melhor te atende.
Uma opção seria abrir a conexão como auto commit false e, então, tentar controlar as ações na camada de negócios, se todas as alterações na base (insert, update ou delete) ocorrerem sem erros, basta invocar o commit. Caso contrário, invocar o rollback.
P
picklesdog70
Penso nisso…
Já abro a conexão com autocommit false… no caso eu tiraria a abertura da conexão da Action abstrata e abriria e fechava em cada Service… por que ai o service poderia chamar “N” DAOs…
Mas como eu passaria a conexão do Service pro DAO? No construtor do DAO? ou em cada Método do DAO?
D
drsmachado
Particularmente eu não gosto dessa abordagem, penso que as conexões se abrem no DAO, você controla a sequência de alterações no service, dentro de um bloco try/catch e garante que chamará o commit ou rollback quando necessário.
P
picklesdog70
Você poderia me mostrar como fazer dessa forma?
P
picklesdog70
Eu estou em dúvida…onde abrir a conexão e controlar a transação… No Service ou no DAO…
Se for no DAO… como fazer quando um service precisar chamar DAOs diferentes que precisam executar todos com sucesso ou nenhum… pq se a conexão estiver no DAO…cada um dará o seu commit né? E pode funcionar um e outro não…
L
LostSoldier
Ao invés de fazer a Action, não seria menos trabalhoso usar um filtro http?
Você pode criar um filtro que abra uma conexão a cada requsição e garante seu fechamento assim que foi processado… na apostila há exemplos…
D
drsmachado1 like
Para isso, normalmente, se utiliza uma classe separada. Eu denomino a mesma como ConnectionUtil, que terá métodos para criar a conexão, fechar a conexão, executar rollback e executar o commit (estáticos ou não).
O método que abre a conexão verifica se a conexão é nula, se for, cria uma nova, senão, devolve a corrente.
Eu ainda não entendi qual a tua necessidade, talvez explicar qual o contexto do problema facilite o entendimento e o apontamento de uma solução. Seguir o que o @LostSoldier sugeriu é uma boa também.
P
picklesdog70
@drsmachado eu estava fazendo isso… uma conexão unica para a aplicação através de um Singleton…e encontrei problemas (Leia aqui >> Ajuda com Singleton )… Então…estou partindo para a opção de abrir uma conexão (Na verdade pega uma do pool) sempre que necessário… Porém estou com muita dúvida em abrir a conexão no DAO…pq estou usando setAutoCommit(false) logo eu preciso controlar o commit() e rollback().
Tenho a necessidade de fazer:
Dao1.save();Dao2.save();Dao3,save();
e garantir q os 3 sejam feitos com sucesso ou rollback caso algum de problema…
Se eu abro a conexão em cada DAO… e dou commit em cada DAO… os que funcionarem vão persistir no banco…e os que derem erro não…
Como alternativa, penso em criar a conexão no SERVICE…abrir a conexão no sERVICE e fazer o commit ou rollback no SERVICE… mas os DAOs precisam de conexão…como mando a conexão do SERVICE para o DAO usar? Através do construtor do DAO? Através de um metodo setConexao do DAO? Essa seria a melhor forma?
P
picklesdog70
Pq eu abriria uma conexão no filtro e fecharia tbm no filtro… se tudo desse certo faria o commit e em caso de erro eu faria o roolback…mas como eu enviaria essa conexão do filtro para o DAO?
L
LostSoldier
Como disse anteriormente, há exemplos no link que mostrei…
// "pendura um objeto no Request" request.setAttribute("connection",connection);
P
picklesdog70
@LostSoldier sim… depois que eu colocar a conexão na request…eu terei que mandá-la para o meu DAO… (No meu caso antes para o meu SERVICE e depois para o DAO) e continuo com a mesma dúvida…
Envio a conexão pelo construtor? Por um método setConexao? Qual a melhor forma de fazer isso?
L
Solucao aceita
LostSoldier
O ideal seria via construção, assim o DAO não tem responsabilidade de abrir, fechar, etc, apenas usa a conexão, dessa forma você está aplicando o conceito de Inversão de Controle…
Além do mais, nesse caso o DAO não precisa de um setConexao, métodos set a grosso modo são para mudar o estado do objeto, e no seu caso creio que não se aplica, já que vocẽ precisa de uma conexão pronta e inalterada…
D
drsmachado
@picklesdog70 me parece que você precisa de algo como o Open Session In View, embora não esteja utilizando um framework JPA, pode adaptar essa abordagem à tua necessidade.