Actions que extendem a Action abstrata e implementam o método process();
public class TripSaveAction extends Action { @Override
public void process() throws Exception {
Trip trip = new Trip();
TripService tripService = new TripService();
tripService.save(trip);
redirect("index.html");
}
}
Service pode chamar um DAO
public class TripService extends Service {
@Override
public Trip save(Trip trip) throws Exception{
try{
TripDao tripDao = new TripDao();
return tripDao.save(trip);
}catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
Por fim, DAOs
public class TripDao extends Dao {
@Override
public Trip save(Trip trip) throws Exception{
try{
PreparedStatement stmt = DbConnectionFactory.getInstance().prepareStatement("INSERT INTO
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.
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í.
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.
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?
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.
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…
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.
@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?
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?
@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?
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…
@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.