正如@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