Java DAO管理事务的设计是否糟糕?

Java DAO管理事务的设计是否糟糕?,java,hibernate,data-access-layer,Java,Hibernate,Data Access Layer,我一直在阅读有关sun blueprintGenericDAO实现以及Gavin King对Hibernate使用此功能的介绍。他似乎没有提到任何关于交易处理的事情: public abstract class GenericHibernateDAO<T, ID extends Serializable> { protected Session getSession() { return HibernateUtil.getSessionFactory().ge

我一直在阅读有关sun blueprint
GenericDAO
实现以及Gavin King对Hibernate使用此功能的介绍。他似乎没有提到任何关于交易处理的事情:

public abstract class GenericHibernateDAO<T, ID extends Serializable> {
    protected Session getSession() {
        return HibernateUtil.getSessionFactory().getCurrentSession();
    }

    public T makePersistent(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }
}

事务处理应该由应用层中DAO的调用方管理吗?

通常,最佳实践是在服务层而不是DAO层中管理事务。每个DAO方法通常处理一个特定的操作,服务方法将它们聚合到一个事务中。

事务应在应用层中进行管理。例如,假设您有一个AccountDAO:

public class AccountDAO {
   public void DebitAccount( int accountId, int dollars ) {

   }

   public void CreditAccount( int accountId, int dollars ) {
   }
}
如果我想在账户之间转账,我会在一个账户上调用
DebitAccount
,在另一个账户上调用
CreditAccount
。我希望这些调用发生在同一事务中。DAO不可能知道这一点,但应用层会知道


如果事务是在DAO层管理的,那么您需要在DAO上创建另一个
TransferMoney
方法,以便在一个事务中完成。这最终会使DAO层膨胀,对于复杂的操作,会引入可能不应该存在的业务逻辑。如果你有一个操作需要多个DAO参与一个事务,那么它会变得更加混乱。

就是这样+1-你比我更了解ITS以贷款系统为例,在贷款系统中,为了决定报价,需要进行大量查询,然后将报价写入DB,你会在所有读取之前启动事务吗?另外,
GenericDao
没有公共方法来检索会话以启动事务?@James-I会在写入之前启动事务,但不一定在读取之前。是的,DAO不需要担心事务,因此不需要方法。事务将在服务层进行管理。好的,谢谢。如果您不介意的话,最后一件事是服务层启动事务,但为了实现这一点,它需要访问“会话”,以便调用
Session.beginTransaction()
。如果不是DAO为服务层提供了
会话
,它来自哪里?静态
SessionFactory
?同样,回到loan示例,所有读取是在单个事务中还是在每次读取时单独进行?@James-关于第一条评论,是的,我认为让服务层从会话工厂获得它会很好。关于第二个问题,读取不会改变任何东西,因此它们不需要成为事务的一部分。您不能“提交”或“回滚”读取,因此根本不需要为只读操作引入事务。
public class AccountDAO {
   public void DebitAccount( int accountId, int dollars ) {

   }

   public void CreditAccount( int accountId, int dollars ) {
   }
}