正如@hvgotcodes所指出的,事務是在服務層而不是在持久層中進行管理的。這是由於事務的含義是事務性的=>大多數時間是由業務定義的,因此是服務/域層。
下面是如何通過Spring AOP XML配置交易服務的例子:
<aop:config>
<aop:pointcut id="moneyMakingBusinessServiceMethods"
expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>
<aop:advisor advice-ref="moneyMakingAdvice"
pointcut-ref="moneyMakingBusinessServiceMethods"/>
</aop:config>
<tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="makeMoney" propagation="REQUIRED"/>
<tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
這種做法是很好的,因爲你並不需要@Transactional
污染你的服務,@SomethingElse
註釋,和你TX管理/配置被定義在一個地方[這是我個人的信念]。
這項服務將花費道/存儲庫或兩個,並委託所有持久運作它:
public class CleverMoneyMakingBusinessService implements MoneyMakingBusinessService {
private MoneyRepository moneyRepository;
public void makeMoney(MoneyRoll money) {
moneyRepository.make(money);
}
public MoneyRoll withdrawMoney(Long moneyRollId) {
return moneyRepository.find(moneyRollId);
}
public void setMoneyRepository(MoneyRepository moneyRepository) {
this.moneyRepository = moneyRepository;
}
}
而存儲庫/ DAO可能看起來像這樣(請注意,它不使用HibernateTemplate
,因爲@Repository
做所有的異常翻譯和Hibernate SessionFactory
可以和應該可以直接使用):
@Repository
public class HibernateMoneyRepository implements MoneyRepository {
private SessionFactory sessionFactory;
public MoneyRoll find(Long rollId) {
MoneyRoll moneyRoll = null;
Query query = getSession().getNamedQuery("find.moneyroll.by.id");
query.setParameter("id", rollId);
List<MoneyRoll> moneyList = query.list();
if (moneyList.size() != 0) {
moneyRoll = (MoneyRoll)query.list().get(0);
}
return moneyRoll;
}
public void make(MoneyRoll moneyRoll) {
getSession().save(moneyRoll);
}
public void takeOut(MoneyRoll moneyRoll) {
getSession().delete(moneyRoll);
}
public void update(MoneyRoll money) {
Query query = getSession().getNamedQuery("update.moneyroll");
query.setParameter("id", money.getId());
query.setParameter("amount", money.getAmount());
query.setParameter("currency", money.getCurrency());
query.executeUpdate();
}
private Session getSession() {
return sessionFactory.getCurrentSession();
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
看看的money making project我把它們作爲一個例子,看看它們是如何結合在一起並執行的。
您能否至少鏈接到一個示例或一些相關文檔?我明白一般的想法是使用一個事務,但在HibernateTemplate API中我沒有看到任何允許這樣做的事情。 – David
第二段中的'configure spring'文本中有一個鏈接。您可能需要在該文檔中聲明性的事務管理。 – hvgotcodes
您可以使用org.springframework.orm.hibernate.HibernateTransactionManager實現。您必須僅設置sessionFactory屬性。在appcontext中使用此行來管理具有註釋的事務: –
lepike