2011-10-12 95 views
0

我有一个java/spring webapp使用HibernateTemplate,我想知道是否有可能使用SQL事务与休眠模板。休眠模板事务

例如,假设我有以下DAO代码:

getHibernateTemplate().save(newObject); 
getHibernateTemplate().saveOrUpdate(someObject); 
getHibernateTemplate().delete(oldObject); 

假设我想要么所有三个语句成功或全部三个失败。有什么办法可以用hibernate模板来完成这个任务吗?我可以使用try/catch块吗?如果是这样,我会放入catch块来回滚hibernate模板语句?

回答

0

使用Spring来管理你的交易(我把它看作你的一个标签)。

其基本思想是将一群持久性操作分组,一个方法(在一个服务类中)要参与一个事务,而另一个方法(configure Spring)使这个服务方法成为事务性的。

一个比较简单的方法就是配置spring来使所有的服务方法都成为事务性的,但是你并没有受到这种限制 - 你可以根据需要简单或复杂。

+0

您能否至少链接到一个示例或一些相关文档?我明白一般的想法是使用一个事务,但在HibernateTemplate API中我没有看到任何允许这样做的事情。 – David

+0

第二段中的'configure spring'文本中有一个链接。您可能需要在该文档中声明性的事务管理。 – hvgotcodes

+0

您可以使用org.springframework.orm.hibernate.HibernateTransactionManager实现。您必须仅设置sessionFactory属性。在appcontext中使用此行来管理具有注释的事务: lepike

2

正如@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我把它们作为一个例子,看看它们是如何结合在一起并执行的。