2012-07-10 86 views
4

我有一个应用程序正在通过jpa对各种数据库表进行一堆写操作。其中一个写入可能导致乐观锁定异常。如果抛出一个,这不是什么大问题,我希望事务的其余部分提交。Jpa事务javax.persistence.RollbackException:标记为rollbackOnly的事务

我看了看通过对弹簧交易无回退功能:

<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> 
    <constructor-arg ref="transactionManager"/> 
    <constructor-arg ref="ignoreOptimisticLockingExceptionRule"/> 
</bean> 
<bean id="ignoreOptimisticLockingExceptionRule" class="org.springframework.transaction.interceptor.RuleBasedTransactionAttribute"> 
    <property name="rollbackRules"> 
     <list> 
      <bean class="org.springframework.transaction.interceptor.NoRollbackRuleAttribute"> 
       <constructor-arg value="javax.persistence.OptimisticLockException"/> 
      </bean> 
     </list> 
    </property> 
</bean> 
<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
    id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

我的应用程序捕捉周围的实体的合并方法,将抛出此异常的OLException,但交易仍然得到回滚。我做了一些深入的研究,看看结果如何,并且在JpaTransactionManager的doCommit方法中javax.persistence.RollbackException:标记为rollbackOnly的事务被抛出。它被抛出是因为rollbackOnly标志(在TransactionImpl中)被标记为true。

深入挖掘,我看到AbstractEntityMangerImpl中的合并方法最终将事务标记为rollbackonly,然后再触发异常。尽管我没有看到RuleBasedTransactionAttributes被应用到哪里。我不知道我是否正确安装了该设置。

谢谢!

回答

4

JPA规范要求事务在发生OptimisticLockException时标记为回滚。我不知道你使用的JPA引擎,但至少对Hibernate(和我希望其他引擎一样的东西),该文件说:

如果Session抛出异常,包括任何的SQLException , 立即回滚数据库事务,调用Session.close() 并丢弃Session实例。会话的某些方法不会 使会话保持一致状态。 没有抛出异常Hibernate可以被视为可恢复。通过在finally块中调用close()来确保会话将会关闭 。

所以如果你有这样的例外,你最好的办法是让事务回滚,然后重试。

+0

嗯,这有点令人失望。所以我的选择基本上是重做一切,因为我不太关心的辅助表具有更多的最新信息,或将两者分开。感谢您的信息。我想我有一个替代解决方法(它是批处理逻辑,并有一个陈旧的对象导致问题)。谢谢! – tfecw 2012-07-10 18:39:52