2012-05-29 26 views
1

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

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

确保它们使用相同的数据库连接。 –

+0

是的,我正在使用相同的数据库连接。 – Harsha

+0

[DAO](http://en.wikipedia.org/wiki/Data_access_object)类通常会收到一个类域对象[POJO或JavaBean](http://en.wikipedia.org/wiki/Plain_Old_Java_Object),其中包含桌子的领域。 –

回答

2

如果使用的是普通的JDBC,你可以做的是分享的Connection同一个实例在DAO类的两个实例。

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

例如为:

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

请记住,'Connection#rollback'和'Connection#close'可能会抛出SQLException,并且应该在'try-catch'块内 –

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

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

关于处理事务的更多信息:

+0

嗨Luiggi,我想知道如果daoObject.getAttribute1()是否可以用daoObject.getParameter替换,或者我必须在控制器层单独执行它? –

+0

@KarenGoh是的,你可以。 –

+0

但是,我不得不使用HTTPRequest req作为参数之一,然后我才能做到这一点?如果我把所有东西都作为一种方法存在,那么我的Controlller图层将在以后如何进入? –