在我的Java应用程序的DAO层中,我有两个DAO类EmployeeDAO
和BankDAO
。我需要控制/处理他们的数据库事务。我使用连接池来获取数据库连接。
EmployeeDAO类:
public class EmployeeDAO {
String name;
String empCode;
int age;
// Getters & Setters
}
BankDAO课程:
public class BankDAO {
String bankName;
String acNo;
String empCode;
// Getters & Setters
}
假设我要在两个数据库表中存储与该员工相关的员工和银行帐户详细信息。首先,我保存员工,第二个我保存银行详细信息,如果发生错误,当存储银行详细信息时,我需要回滚完成交易。
如何在使用DAO时管理此类事务?
答案 0 :(得分:3)
如果您使用普通JDBC,那么您可以做的是在DAO类的两个实例中共享同一个Connection
实例。
public class EmployeeDAO {
private Connection conn;
public void setConnection(Connection conn) {
this.conn = conn;
}
...
}
public class BankDAO {
private Connection conn;
public void setConnection(Connection conn) {
this.conn = conn;
}
...
}
在客户端代码中,首先需要创建一个Connection
对象实例。接下来,您需要使用conn.setAutoCommit(false);
启动交易。将Connection
对象实例传递给两个DAO类。如果在任何操作中都没有出现错误,conn.commit();
,否则为conn.rollback();
e.g:
Connection conn = null;
try {
// getConnection from pool
conn.setAutoCommit(false);
EmployeeDAO employeeDAO = new EmployeeDAO();
employeeDAO.setConnection(conn);
BankDAO bankDAO = new BankDAO();
bankDAO.setConnection(conn);
// save employee
// save bank details
conn.commit();
catch(Exception e) {
if (conn != null) {
conn.rollback();
}
} finally {
if (conn != null) {
conn.close();
}
}
答案 1 :(得分:2)
当您从数据库打开连接时,可以使用方法[Connection#setAutoCommit][1](false)
启动新事务,执行所有插入/更新/删除操作并执行提交以保存所有这些更改,以防出现错误您可以回滚所有操作或保存点。以下是我所说的一个例子:
public void saveSomeData(DAOClass daoObject) {
Connection con = null;
try {
con = getConnectionFromDBPool(); //get the connection from the connection pool
con.setAutoCommit(false);
//start your transaction
PreparedStatement ps = con.prepareCall("insert into tablex values(?, ?)");
ps.setInt(1, daoObject.getAttribute1());
ps.setString(2, daoObject.getAttribute2());
ps.execute();
//add another insert/update/delete operations...
//at the end, you commit the transaction
con.commit();
} catch (Exception e) {
//start a rollback
if (con != null) {
try {
con.rollback();
} catch (Exception ex) {
}
}
//handle the exception
e.printStackTrace();
} finally {
if (con != null) {
try {
con.close();
} catch (Exception e) {
}
}
}
}
另一个提示:您应该在关闭连接之前手动关闭所有资源。这段代码只是解释性的,但我应该在使用它之后关闭准备好的语句。
有关处理交易的更多信息: