Spring + Hibernate如何防止回滚

时间:2014-02-27 14:21:54

标签: spring hibernate transactions

我有一个使用此方法的代码块:

@Transactional(noRollbackFor=Exception.class)
public synchronized Object saveData(){
    //...
    dao.insert(entity);
    //...
}

我的dao类标记为广告交易

@Transactional
public class Dao {
   //...
   public <T> void insert(T obj) throws Exception {
    getSession().saveOrUpdate(obj);
   }
}

我需要阻止此块内的任何回滚。但是我得到了这个:

2014-02-25 20:47:44 [WARN]SqlExceptionHelper:143    SQL Error: 1205, SQLState: 41000
2014-02-25 20:47:44 [ERROR]SqlExceptionHelper:144   Lock wait timeout exceeded; try restarting transaction
2014-02-25 20:47:44 [ERROR]BigliettiService:?   Transazione in errore
org.hibernate.exception.GenericJDBCException: Lock wait timeout exceeded; try restarting transaction
...
2014-02-25 20:47:44 [ERROR]JsonHandlerExceptionResolver:?   Transaction rolled back because it has been marked as rollback-only

为什么最后我发现交易已回滚?

2 个答案:

答案 0 :(得分:3)

上周我有类似的问题。在我的例子中,它是来自不同方法的另一个@Transactional注释,导致事务被标记为仅回滚。

你有没有检查过呢?

编辑:为了澄清一点,您没有在saveData()方法中发布代码。导致此错误的原因是在我的方法@Transactional中调用了noRollback(缺少saveData()属性)的另一种方法。

答案 1 :(得分:1)

我认为你不能那样做。您的事务默认传播到内部方法,如果此方法回滚您的事务,则外部方法只能通过UnexpectedRollbackException通知回滚已经发生..并确认它。

您可以更改传播配置以启动新的内部事务,但这无济于事,因为它仍然会在到达外部事务之前独立提交。

如果你不能在DAO级别设置NoRollback属性,我想最好的解决方案是从你的DAO中删除Transactional属性,并有一层Facade服务调用这些DAO并定义自己的回滚策略。