使用DAO进行事务管理

在我的Java应用程序的DAO层中,我有两个DAO类EmployeeDAOBankDAO 。 我需要控制/处理他们的数据库事务。 我使用连接池来获取数据库连接。

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时管理此类事务?

如果您使用的是普通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);启动事务conn.setAutoCommit(false); 。 将Connection对象实例传递给两个DAO类。 如果在任何操作中都没有发生错误, conn.commit(); ,否则, conn.rollback();

例如:

 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(); } } 

当您从数据库打开连接时,可以使用[Connection#setAutoCommit][1](false)方法启动新事务,执行所有插入/更新/删除操作并执行commit以保存所有这些更改,以防万一您可以回滚所有操作或保存点的错误。 这是我所说的一个例子:

 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) { } } } } 

另一个提示:您应该在关闭连接之前手动关闭所有资源。 这段代码只是解释性的,但是我应该在使用它之后关闭准备好的语句。

有关处理交易的更多信息:

  • 使用交易