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 {
EnderecoDAO daoe = new EnderecoDAO(con);
AlunoDAO daoa = new AlunoDAO(con);
//set auto commit to false
con.setAutoCommit(false);
daoe.incluir(endereco_aluno);
daoa.incluir(a);
//now commit transaction
con.commit();
try {
EnderecoDAO daoe = new EnderecoDAO(con);
AlunoDAO daoa = new AlunoDAO(con);
//set auto commit to false
con.setAutoCommit(false);
daoe.incluir(endereco_aluno);
daoa.incluir(a);
//now commit transaction
con.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
con.rollback();
System.out.println("JDBC Transaction rolled back successfully");
} catch (SQLException e1) {
System.out.println("SQLException in rollback"+e.getMessage());
}
} finally {
try {
if (con != null)
con.close();
} catch (SQLException e) {
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.
Coloquei a exception conforme você comentou, porém, se o último insert falhar ele não executa o rollback.
Connection con = new ConexaoBD().getConnection();
try {
//set auto commit to false
con.setAutoCommit(false);
EnderecoDAO daoe = new EnderecoDAO(con);
AlunoDAO daoa = new AlunoDAO(con);
PaiDAO daop = new PaiDAO(con);
MaeDAO daom = new MaeDAO(con);
daoe.incluir(endereco_pai);
daop.incluir(pai);
daoe.incluir(endereco_mae);
daom.incluir(mae);
daoe.incluir(endereco_aluno);
daoa.incluir(a);
//now commit transaction
System.out.println("TESTE....");
con.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
con.rollback();
System.out.println("JDBC Transaction rolled back successfully");
} catch (SQLException e1) {
System.out.println("SQLException in rollback" + e.getMessage());
}
} catch (RuntimeException ex1) {
ex1.printStackTrace();
try {
con.rollback();
System.out.println("JDBC Transaction rolled back successfully");
} catch (SQLException e1) {
System.out.println("SQLException in rollback" + e1.getMessage());
}
} finally {
try {
if (con != null) {
con.rollback();
}
con.close();
} catch (SQLException ex2) {
ex2.printStackTrace();
}
}
}
Fernando, obrigado. Eu já li esse post, ajudou em alguns conceitos.
Fernando, li este post http://fernandofranzini.wordpress.com/2011/09/05/escopo-thread-local/
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
Fernando, li este post http://fernandofranzini.wordpress.com/2011/09/05/escopo-thread-local/
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[/quote]
± isso…nos DAO’s vc pega a connection da threadlocal e faz SQL executar dentro da mesma transação
Fernando, li este post http://fernandofranzini.wordpress.com/2011/09/05/escopo-thread-local/
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[/quote]
± isso…nos DAO’s vc pega a connection da threadlocal e faz SQL executar dentro da mesma transação[/quote]
Aqui o seu ThreadLocal retorna o string. No meu caso deveria ser o Connection?
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.
*/
package teste;
import java.sql.Connection;
import java.sql.SQLException;
import util.ConexaoBD;
/**
*
* @author Emerson
*/
public class Transaction {
private static final ThreadLocal localConnection = new ThreadLocal();
public static void start() throws SQLException {
Connection con = new ConexaoBD().getConnection(); // Initialized connection ...
con.setAutoCommit(false);
localConnection.set(con);
}
public static Connection getConnection() {
return (Connection) localConnection.get();
}
public static void commit() throws SQLException {
Connection con = getConnection();
con.commit();
con.close();
localConnection.set(null);
}
public static void rollback() throws SQLException {
Connection con = getConnection();
con.rollback();
con.close();
localConnection.set(null);
}
}
/////// Lógica
Connection con = Transaction.getConnection();
try {
Transaction.start();
// Invoke your DAO ...
EnderecoDAO daoe = new EnderecoDAO();
AlunoDAO daoa = new AlunoDAO();
PaiDAO daop = new PaiDAO();
MaeDAO daom = new MaeDAO();
daoe.incluir(endereco_pai);
daop.incluir(pai);
daoe.incluir(endereco_mae);
daom.incluir(mae);
daoe.incluir(endereco_aluno);
daoa.incluir(a);
Transaction.commit();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
try {
Transaction.rollback();
} catch (SQLException ex1) {
System.out.println(ex1.getMessage());
}
} catch (RuntimeException ex) {
System.out.println(ex.getMessage());
try {
System.out.println("Vou fazer o rollback...");
Transaction.rollback();
} catch (SQLException ex1) {
System.out.println(ex1.getMessage());
}
}
//// Em cada DAO, acredito que posso passar o Connection pelo construtor.
this.con = Transaction.getConnection(); ;