2017-02-22 15 views
1

トランザクションでデータベースに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を返すが、これは何のロールバックが実行されないことを意味します。

大きな問題は、なぜ私のトランザクションがもはやアクティブではないことです。

答えて

1

まあ、問題はmysqlだったようですが、バネデータjpaによって生成されるテーブルはmyisam型です。

いくつかの種類のトランザクションを使用するとmyisamがうまくいくようです。

私はInnoDBテーブルに私のテーブルに変換し、今では動作します:トランザクションが失敗し、トランザクションがロールバックされたときに挿入されたすべての行が削除されます。これは、テーブルのタイプがmyisamの場合には発生しません。

関連する問題