弹簧数据JPA嵌套交易回滚未删除插入



我尝试在交易中将2个记录插入2个记录。第二个插件失败,但在回滚中,第一个插件未删除:

   @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保存,但问题仍然存在)

我启用了交易记录以查看正在发生的事情,我发现了:

在调用test()之前创建了新事务,因为 @transactional annotaion:

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=[],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

退出test()已完成提交:

 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)中。

不确定这是否意味着什么,但是在犯罪中我们有:插入= executablist {size = 2}但是回滚是:插入= executablist {size = 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,这意味着没有执行回滚。

现在的最大问题是为什么我的交易不再活动了?

好吧,似乎问题是mysql,春季数据生成的表jpa类型是myisam。

使用某些类型的交易时,Myisam似乎很不高兴。

我将表转换为InnoDB,现在起作用:当交易失败和交易是回滚时,所有插入的行均被删除。当表格为Myisam时,这不会发生。

最新更新