DAO管理交易的设计是否糟糕?

时间:2010-06-24 17:54:31

标签: java hibernate data-access-layer

我一直在阅读有关太阳蓝图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;
    }
}

我很困惑我应该把交易的开始/结束放在哪里。目前,它们位于扩展此GenericHibernateDAO

的DAO中
public class FooHibernateDAO extends GenericHibernateDAO<Foo, Long> {
    public Foo saveFoo(Foo foo) {
        getSession().beginTransaction();
        makePersistent(foo);
        getSession().getTransaction().commit();
    }
}

交易处理是否应由应用程序层中DAO的调用者管理?

2 个答案:

答案 0 :(得分:16)

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

答案 1 :(得分:3)

应在应用程序层管理事务。比如你有一个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参与单个事务,那么它会变得更加混乱。