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

4
我有一个应用程序,通过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中的合并方法最终将事务标记为rollbackonly,从而进一步触发异常。我不知道RuleBasedTransactionAttributes何时应用。我不知道我是否已正确设置它。
谢谢!
1个回答

4
JPA规范规定,当出现OptimisticLockException异常时,事务将被标记为回滚。我不知道您使用的是哪个JPA引擎,但至少对于Hibernate(我希望其他引擎也是这样),文档中说:
如果Session抛出异常,包括任何SQLException,请立即回滚数据库事务,调用Session.close()并丢弃Session实例。某些Session方法将不会使Session处于一致状态。Hibernate抛出的任何异常都不能被视为可恢复的。确保通过在finally块中调用close()来关闭Session。
所以,如果您遇到这样的异常,最好让事务回滚并重试。

嗯,有点糟糕。所以我的选择基本上是重新做一切,因为一个我并不太关心的辅助表格有更多当前信息,或者将它们分开。感谢提供信息。我想我有一个替代解决方案(这是批处理逻辑,有一个过时的对象导致了问题)。谢谢! - tfecw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接