トランザクションでデータベースに2つのレコードを挿入しようとしました。第2のインサートは失敗するが、ロールバックの最初のインサートが削除されない:スプリングデータjpaネストされたトランザクションロールバックは挿入を削除しませんか?
@Resource
private WebMessageRep rep; //<-- extends JpaRepository
@Transactional
public void test() {
WebMessage wm = new WebMessage(.valid params.);
wm = rep.save(wm);//<-- save is crud save which is transactional by default
WebMessage wm2 = new WebMessage(.invalid params.);
rep.save(wm2);
}
(私もで保存方法を交換しようとした: jpaContext.getEntityManagerByManagedType(WebMessage.class).persist(WM); よう私は私が発見し、何が起こっているかを確認するために、トランザクション・ログを有効)CRUDを保存使用しますが、問題がまだ存在しませ
行います
テスト()を呼び出す前に@Transactionalため、新しいトランザクションが作成されますannotaion:
Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
第二のセーブは、第1のトランザクション見ている:最初のトランザクション見救う最初の呼び出し
Creating new transaction with name [com..data.webmessage.WebMessageServiceImpl.test]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
Opened new EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
、
Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com..shared.WebMessage#107]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=1} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
2017-02-22 14:07:22,000 [ main] DEBUG orm.jpa.JpaTransactionManager - Participating in existing transaction
出テストを()Aコミットが行われます。
Committing JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com..shared.WebMessage#108], EntityKey[com..shared.WebMessage#107]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=2} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
失敗します。
Column 'text' cannot be null
HHH000010: On release of batch it still contained JDBC statements
HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
Initiating transaction rollback after commit exception
ロールバック:
Rolling back JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
奇妙なことは、(MySQLの)最初の挿入されたレコードは、私のデータベースにまだあるということです。それが何を意味しますがで、我々が持っているコミット場合
わからない: 挿入= ExecutableList {サイズ= 2} が、上のそれはロールバック: 挿入= ExecutableList {サイズ= 0}
は、誰もが、なぜそれを知っています最初のインサートをロールバックしていませんか?
私のトランザクションの設定は非常に簡単です:私のデバッガはロールバックが試みられたとき、私のトランザクションはもはや有効ではないことを明らかにしたアップ焼成
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
。私に説明してみましょう:
は[JpaTransactionManager.java]
@Override
protected void doRollback(DefaultTransactionStatus status) {
JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Rolling back JPA transaction on EntityManager [" +
txObject.getEntityManagerHolder().getEntityManager() + "]");
}
try {
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction();
if (tx.isActive()) {
tx.rollback();
}
}
catch (PersistenceException ex) {
throw new TransactionSystemException("Could not roll back JPA transaction", ex);
}
finally {
if (!txObject.isNewEntityManagerHolder()) {
// Clear all pending inserts/updates/deletes in the EntityManager.
// Necessary for pre-bound EntityManagers, to avoid inconsistent state.
txObject.getEntityManagerHolder().getEntityManager().clear();
}
}
}
上記のコードでtx.isActive()がfalseを返すが、これは何のロールバックが実行されないことを意味します。
大きな問題は、なぜ私のトランザクションがもはやアクティブではないことです。