JPA事务javax.persistence.RollbackException:事务标记为rollbackOnly [英] Jpa transaction javax.persistence.RollbackException: Transaction marked as rollbackOnly

查看:150
本文介绍了JPA事务javax.persistence.RollbackException:事务标记为rollbackOnly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序正在通过jpa对各种数据库表进行大量写操作.这些写操作之一可能导致乐观锁异常.如果抛出一个,那没什么大不了的,我希望其余的事务得以落实.

I've got an application that's doing a bunch of writes to various database tables via jpa. One of those writes can cause an optimistic lock exception. If one is thrown, it's not a big deal and I want the rest of the transaction to commit.

我通过以下方式查看了春季交易的无回滚功能:

I took a look at the no-rollback functionality on the spring transaction via:

<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.

My app catches the OLException around the merge method of the entity that will throw this exception, but the transaction still gets rolled back. I did some digging around to see what was up, and in the doCommit method of JpaTransactionManager is where javax.persistence.RollbackException: Transaction marked as rollbackOnly gets thrown. It gets thrown because the rollbackOnly flag (in TransactionImpl) was marked as true.

更深入地了解这一点,我发现AbstractEntityMangerImpl中的merge方法最终将事务标记为rollbackonly,然后进一步触发异常.我看不到RuleBasedTransactionAttributes在哪里应用.我不知道我的安装是否正确.

Digging deeper into that, i see that merge method in AbstractEntityMangerImpl ultimately marks the transaction as rollbackonly which then triggers the exception further up. I don't see where the RuleBasedTransactionAttributes get applied though. I don't know if i have that setup properly.

谢谢!

推荐答案

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

The JPA specification mandates that the transaction is marked for rollback when an OptimisticLockException occurs. And I don't know which JPA engine you use, but at least for Hibernate (and I would expect the same thing for other engines), the documentation says:

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

If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.

因此,如果遇到此类异常,最好的选择是让事务回滚并重试.

So if you get such an exception, your best bet is to let the transaction rollback, and retry.

这篇关于JPA事务javax.persistence.RollbackException:事务标记为rollbackOnly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆