Boa tarde.
Tenho um projeto acadêmico que trabalha com vários DAOs.
Como faço para controlar uma transação? Na maneira que esta tentando fazer quando ocorre um erro na classe AlunoDAO ele não entra no rollback.
Connection con = new ConexaoBD().getConnection();
try {
EnderecoDAOdaoe=newEnderecoDAO(con);AlunoDAOdaoa=newAlunoDAO(con);//set auto commit to falsecon.setAutoCommit(false);daoe.incluir(endereco_aluno);daoa.incluir(a);//now commit transactioncon.commit();
try {
EnderecoDAOdaoe=newEnderecoDAO(con);AlunoDAOdaoa=newAlunoDAO(con);//set auto commit to falsecon.setAutoCommit(false);daoe.incluir(endereco_aluno);daoa.incluir(a);//now commit transactioncon.commit();}catch(SQLExceptione){e.printStackTrace();try{con.rollback();System.out.println("JDBC Transaction rolled back successfully");}catch(SQLExceptione1){System.out.println("SQLException in rollback"+e.getMessage());}}finally{try{if(con!=null)con.close();}catch(SQLExceptione){e.printStackTrace();}}}
Amigo, coloque seu código dentro da tag por favor.
Na onde o código não executa exatamente dentro da sua classe? Explique melhor!!! Percebi que você fez vários try/catch, tente fazer uso do finally.
Verifique o tipo da exception que está sendo chamada, as vezes não é do tipo SQLException e realmente não vai ser capturada.
E
emerson82
Coloquei a exception conforme você comentou, porém, se o último insert falhar ele não executa o rollback.
Connectioncon=newConexaoBD().getConnection();try{//set auto commit to falsecon.setAutoCommit(false);EnderecoDAOdaoe=newEnderecoDAO(con);AlunoDAOdaoa=newAlunoDAO(con);PaiDAOdaop=newPaiDAO(con);MaeDAOdaom=newMaeDAO(con);daoe.incluir(endereco_pai);daop.incluir(pai);daoe.incluir(endereco_mae);daom.incluir(mae);daoe.incluir(endereco_aluno);daoa.incluir(a);//now commit transactionSystem.out.println("TESTE....");con.commit();}catch(SQLExceptione){e.printStackTrace();try{con.rollback();System.out.println("JDBC Transaction rolled back successfully");}catch(SQLExceptione1){System.out.println("SQLException in rollback"+e.getMessage());}}catch(RuntimeExceptionex1){ex1.printStackTrace();try{con.rollback();System.out.println("JDBC Transaction rolled back successfully");}catch(SQLExceptione1){System.out.println("SQLException in rollback"+e1.getMessage());}}finally{try{if(con!=null){con.rollback();}con.close();}catch(SQLExceptionex2){ex2.printStackTrace();}}}
FernandoFranzini
E
emerson82
Fernando, obrigado. Eu já li esse post, ajudou em alguns conceitos.
Como eu poderia utilizar a minhas classes DAOs aqui? Preciso compartilhar apenas o Connection?
Na classe Regra eu faria as chamadas para os demais DAOs?
OBrigado.
Emerson
± isso…nos DAO’s vc pega a connection da threadlocal e faz SQL executar dentro da mesma transação
Aqui o seu ThreadLocal retorna o string. No meu caso deveria ser o Connection?
FernandoFranzini
Troca o generics
E
emerson82
Um dos problemas que encontrei foi que o mysql está setado como MyISAM, preciso converter para InnoDB para ter suporte a transação. Implementei o seguinte código no SQL Server 2008 e funcionou.
Implementei a ideia de uma thread local.
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */packageteste;importjava.sql.Connection;importjava.sql.SQLException;importutil.ConexaoBD;/** * * @author Emerson */publicclassTransaction{privatestaticfinalThreadLocallocalConnection=newThreadLocal();publicstaticvoidstart()throwsSQLException{Connectioncon=newConexaoBD().getConnection();// Initialized connection ...con.setAutoCommit(false);localConnection.set(con);}publicstaticConnectiongetConnection(){return(Connection)localConnection.get();}publicstaticvoidcommit()throwsSQLException{Connectioncon=getConnection();con.commit();con.close();localConnection.set(null);}publicstaticvoidrollback()throwsSQLException{Connectioncon=getConnection();con.rollback();con.close();localConnection.set(null);}}/////// LógicaConnectioncon=Transaction.getConnection();try{Transaction.start();// Invoke your DAO ...EnderecoDAOdaoe=newEnderecoDAO();AlunoDAOdaoa=newAlunoDAO();PaiDAOdaop=newPaiDAO();MaeDAOdaom=newMaeDAO();daoe.incluir(endereco_pai);daop.incluir(pai);daoe.incluir(endereco_mae);daom.incluir(mae);daoe.incluir(endereco_aluno);daoa.incluir(a);Transaction.commit();}catch(SQLExceptionex){System.out.println(ex.getMessage());try{Transaction.rollback();}catch(SQLExceptionex1){System.out.println(ex1.getMessage());}}catch(RuntimeExceptionex){System.out.println(ex.getMessage());try{System.out.println("Vou fazer o rollback...");Transaction.rollback();}catch(SQLExceptionex1){System.out.println(ex1.getMessage());}}//// Em cada DAO, acredito que posso passar o Connection pelo construtor. this.con=Transaction.getConnection();;