java Jpa 事务 javax.persistence.RollbackException:事务标记为 rollbackOnly
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11418290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jpa transaction javax.persistence.RollbackException: Transaction marked as rollbackOnly
提问by tfecw
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.
我有一个应用程序通过 jpa 对各种数据库表进行大量写入。其中一个写入可能会导致乐观锁异常。如果抛出一个,这没什么大不了的,我希望事务的其余部分提交。
I took a look at the no-rollback functionality on the spring transaction via:
我通过以下方式查看了 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>
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.
我的应用程序在将抛出此异常的实体的合并方法周围捕获 OLException,但事务仍会回滚。我做了一些挖掘,看看发生了什么,在 JpaTransactionManager 的 doCommit 方法中,javax.persistence.RollbackException: Transaction 标记为 rollbackOnly 被抛出。它被抛出是因为 rollbackOnly 标志(在 TransactionImpl 中)被标记为 true。
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.
深入研究,我看到 AbstractEntityMangerImpl 中的合并方法最终将事务标记为 rollbackonly,然后进一步触发异常。我没有看到 RuleBasedTransactionAttributes 在哪里应用。我不知道我的设置是否正确。
Thanks!
谢谢!
采纳答案by JB Nizet
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:
JPA 规范要求在发生 OptimisticLockException 时将事务标记为回滚。而且我不知道您使用的是哪种 JPA 引擎,但至少对于 Hibernate(我希望其他引擎也能如此),文档说:
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.
如果 Session 抛出异常,包括任何 SQLException,立即回滚数据库事务,调用 Session.close() 并丢弃 Session 实例。Session 的某些方法不会使会话处于一致状态。Hibernate 抛出的异常不能被视为可恢复的。通过在 finally 块中调用 close() 确保会话将被关闭。
So if you get such an exception, your best bet is to let the transaction rollback, and retry.
所以如果遇到这样的异常,最好的办法是让事务回滚,然后重试。