Я читал о проекте солнца GenericDAO
реализация и Gavin King берет, это для использования с В спящем режиме. Кажется, что он ничего не упоминает об обработке транзакции:
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
public class FooHibernateDAO extends GenericHibernateDAO<Foo, Long> {
public Foo saveFoo(Foo foo) {
getSession().beginTransaction();
makePersistent(foo);
getSession().getTransaction().commit();
}
}
Обработка транзакции должна быть организована вызывающей стороной ДАО на уровне приложений?
Как правило, лучше всего управлять транзакциями на уровне обслуживания, а не на уровне DAO. Каждый метод DAO обычно обрабатывает одну конкретную операцию, а метод службы объединяет их в одну транзакцию.
Транзакции должны управляться на уровне приложения. Допустим, у вас есть AccountDAO:
public class AccountDAO {
public void DebitAccount( int accountId, int dollars ) {
}
public void CreditAccount( int accountId, int dollars ) {
}
}
Если бы я хотел перевести деньги между счетами, я бы вызвал DebitAccount
на одном счете и CreditAccount
на другом. Я бы хотел, чтобы эти вызовы происходили в одной и той же транзакции. DAO не может знать этого, но уровень приложения знает.
Если бы транзакции управлялись на уровне DAO, вам пришлось бы создать еще один метод TransferMoney
на DAO, чтобы сделать это в одной транзакции. В конечном итоге это привело бы к раздуванию уровня DAO и, в случае сложных операций, к появлению бизнес-логики, которой там, вероятно, быть не должно. И все становится еще более запутанным, если у вас есть операция, которая требует участия нескольких DAO в одной транзакции.