Jpa事务javax.persistence.RollbackException:事务标记为rollbackOnly

时间:2012-07-10 17:02:32

标签: java spring jpa

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

我通过以下方式查看了spring事务处的无回滚功能:

<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中的merge方法最终将事务标记为rollbackonly,然后进一步触发异常。我没有看到RuleBasedTransactionAttributes应用于哪里。我不知道我是否有正确的设置。

谢谢!

1 个答案:

答案 0 :(得分:4)

JPA规范要求在发生OptimisticLockException时将事务标记为回滚。而且我不知道你使用哪种JPA引擎,但至少对于Hibernate而言(我希望其他引擎能做同样的事情),文档说:

  

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

因此,如果您遇到此类异常,最好的办法是让事务回滚,然后重试。

相关问题