当前位置: 首页 > 知识库问答 >
问题:

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

潘宪
2023-03-14

我有一个应用程序通过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的事务将被抛出。它被抛出,因为回滚标志(在TransactionImpl中)被标记为true。

深入研究一下,我发现AbstractEntityMangerImpl中的merge方法最终将事务标记为rollbackonly,然后进一步触发异常。不过,我看不出RuleBasedTransactionAttributes应用于何处。我不知道我的设置是否正确。

谢啦!

共有1个答案

严劲
2023-03-14

JPA 规范要求在发生 OptimisticLockException 时将事务标记为回滚。我不知道你使用哪个JPA引擎,但至少对于Hibernate(我期望其他引擎也是如此),文档说:

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

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

 类似资料:
  • 问题内容: 我在正在使用的一个应用程序中使用Spring和Hibernate,但是在处理事务时遇到了问题。 我有一个服务类,该类从数据库中加载一些实体,修改它们的一些值,然后(当所有内容都有效时)将这些更改提交给数据库。如果新值无效(我只能在设置它们后检查),但我不想保留更改。为了防止Spring / Hibernate保存更改,我在方法中抛出异常。但是,这导致以下错误: 这是服务: 这就是我调用

  • 我在一个应用程序中使用Spring和Hibernate,我在处理事务时遇到了问题。 我有一个服务类,它从数据库加载一些实体,修改它们的一些值,然后(当一切都有效时)将这些更改提交给数据库。如果新值无效(我只能在设置它们后检查),我不想保留更改。为了防止Spring/Hibernate保存更改,我在方法中抛出一个异常。但是,这会导致以下错误: 这就是服务: 我就是这样调用它的: 我希望发生的事情是:

  • 我正在为应用程序使用Spring data JPA的存储库。目前,我正在使用spring data jpa存储库默认提供的基本CRUD操作,对于复杂的join查询,我正在编写定制的JPQL查询,如下所示: 在我的服务类中,我自动生成这个存储库并执行DB操作。 目前,我只是将标记为。 我是否也应该将方法标记为?因为它只执行读取操作。 我是否也应该将标记为事务性(readOnly=true)?我读到所

  • 我无意中发现我可以在对象上保留更改,即使我没有在事务中写入它们。我想知道这是怎么发生的,因为理论上,如果我不在事务中写入更改,我应该无法更改数据库中的年龄值。PS:如果我删除最后2行,它不会像预期的那样对db产生任何影响。

  • 问题内容: 我在@Transactional方法中提交事务时遇到问题: 当我从methodA()调用methodB()时,该方法成功通过,并且可以在日志中看到“确定”。但后来我明白了 在异常中完全缺少methodB的上下文-我想可以吗? methodB()中的某些内容将事务标记为仅回滚?我如何找到它?例如,有没有一种方法可以检查类似的东西-这样,我可以逐步检查方法并找到原因。 问题答案: 我终于明

  • 问题内容: 我在@Transactional方法中提交事务时遇到问题: 当我从methodA()调用methodB()时,该方法成功通过,并且可以在日志中看到“确定”。但后来我明白了 在异常中完全缺少methodB的上下文-我想这可以吗? methodB()中的某些内容将事务标记为仅回滚?我如何找到它?例如,是否有一种检查类似方法的方法-这样,我可以逐步检查方法并找到原因。 问题答案: 我终于明白