【发布时间】:2015-12-28 16:39:57
【问题描述】:
我正在寻找一种在事务中调用多个 DAO 函数的方法,但我没有使用 spring 或任何此类框架。我们实际拥有的是一个数据库 api 类型.jar,它使用使用的数据源进行初始化。我想要实现的是让我的业务逻辑级代码执行以下操作:
Connection conn = datasource.getConnection();
conn.setAutoCommit(false);
DAOObject1.query1(params, conn);
DAOObject2.query4(params, conn);
conn.commit();
conn.setAutoCommit(false);
但是我想避免在每个函数中传递连接对象,因为这不是正确的方法。现在,在我们拥有的少数事务中,我们使用它,但我们正在寻找一种方法来停止将连接对象传递给数据库层,甚至在它之外创建它。我正在寻找类似的东西:
//Pseudocode
try{
Datasource.startTransactionLogic();
DAO1.query(params);
DAO2.query(params);
Datasource.endAndCommitTransactionLogic();
}
catch(SQLException e){
Datasource.rollbackTransaction();
}
我可以通过 EJB 实现这一点吗?现在我们不是通过注入使用 DAO,而是手动创建它们,但我们即将迁移到 EJB 并开始通过容器使用它们。我听说 EJB 执行的所有查询都是事务性的,但它怎么知道回滚到什么?通过savepoints?
编辑:
让我指出,现在每个DAO 对象的方法都获得了自己的连接对象。以下是我们的 DAO 类的示例:
public class DAO {
public DTO exampleQueryMethod(Integer id) {
DTO object = null;
String sql = "SELECT * FROM TABLE_1 WHERE ID = ?";
try (
Connection connection = datasourceObject.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)
) {
statement.setInt(1, id);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
object = DAO.map(resultSet);
}
}
}
return object;
}
}
现在我们对需要在事务中的方法做的是让它们的第二个副本接收Connection 对象:
public void exampleUpdateMethod(DTO object, Connection connection) {
//table update logic
}
我们想要的是避免在我们的“数据库 api”.jar 中使用此类方法,而是能够在我们的业务逻辑层中定义事务的开始和提交,就像上面的伪代码中提到的那样。
【问题讨论】:
-
使用 EJB(或 Spring),您将拥有比您想要的更简单、更安全和可重用的东西。无需通过代码启动、提交和回滚事务。如果事务方法抛出运行时异常,事务将自动回滚。
-
是的,但我正在寻找一种实现事务逻辑的方法。我可以在调用多个 DAO 方法的函数上添加
@Transactional并让它在运行时异常上重新滚动所有数据库更改吗?例如,我有一个创建对象的方法,然后将信息写入 2 个不同的表(总共 3 个 DAO 方法)。如果第三种方法抛出运行时异常,我想回滚所有内容,甚至是对象创建。 -
是的,这正是 EJB 和 Spring 事务方法所做的。
-
好的,谢谢,我去看看
-
@Konstantine JBNizet 的回答是正确的,但是......你真的需要迁移到 EJB 吗?甚至事务在那里也不是很直观:将您的异常包装到
javax.ejb.EJBException既不灵活也不可读。更不用说其他问题了,比如启动时间或集成测试。
标签: java transactions ejb cdi jta