4

jpaを介してさまざまなデータベーステーブルに大量の書き込みを行うアプリケーションがあります。これらの書き込みの1つにより、楽観的なロック例外が発生する可能性があります。1つがスローされた場合、それは大したことではなく、トランザクションの残りの部分をコミットする必要があります。

次の方法で、春のトランザクションのロールバックなしの機能を確認しました。

<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がどこに適用されるのかわかりません。その設定が適切かどうかはわかりません。

ありがとう!

4

1 に答える 1

4

JPA仕様では、OptimisticLockExceptionが発生したときにトランザクションにロールバックのマークを付けることが義務付けられています。また、どのJPAエンジンを使用しているかはわかりませんが、少なくともHibernateの場合(他のエンジンでも同じことを期待します)、ドキュメントには次のように記載されています。

セッションがSQLExceptionを含む例外をスローした場合は、データベーストランザクションをすぐにロールバックし、Session.close()を呼び出して、Sessionインスタンスを破棄します。セッションの特定のメソッドは、セッションを一貫した状態のままにしません。Hibernateによってスローされた例外は、回復可能として扱うことはできません。finallyブロックでclose()を呼び出して、セッションが閉じられることを確認します。

したがって、このような例外が発生した場合は、トランザクションをロールバックさせて再試行するのが最善の策です。

于 2012-07-10T17:58:25.047 に答える