Example usage for org.springframework.transaction.support DefaultTransactionStatus isNewTransaction

List of usage examples for org.springframework.transaction.support DefaultTransactionStatus isNewTransaction

Introduction

In this page you can find the example usage for org.springframework.transaction.support DefaultTransactionStatus isNewTransaction.

Prototype

@Override
    public boolean isNewTransaction() 

Source Link

Usage

From source file:com.eclecticlogic.pedal.impl.JPATransactionWrapper.java

@Override
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
    super.prepareSynchronization(status, definition);
    if (status.isNewTransaction()) {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapterData());
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapterTask());
    }//from  www .  ja v  a2 s  .  c o m
}

From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManager.java

@Override
protected void doRollback(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException {
    // Sanity check on precondition -----------------------------------------------------------
    /* When logic flow got here, it should be not the case of participating existing transaction that  
     * means the target method is the outer most transactional method what began a transaction process 
     * at the first, and that also means newTransaction boolean member field of DefaultTransactionStatus 
     * object should be true.//from  w w  w.j av a  2s  . co  m
     */
    if (!defaultTransactionStatus.isNewTransaction()) {
        // Could be caused by unaware code change on org.springframework.transaction.support.AbstractPlatformTransactionManager
        throw new TransactionSystemException(String.format(
                "Unexpected system state: attempting to roll back from participation of an "
                        + "existing transaction (of which GlobalTransacion Id is %1$s).",
                ((defaultTransactionStatus.getTransaction() instanceof GlobalTransaction)
                        ? ((GlobalTransaction) defaultTransactionStatus.getTransaction()).getId()
                        : "null")));
    }
    // ----------------------------------------------------------------------------------------

    // Check on GlobalTransaction instance ----------------------------------------------------
    GlobalTransaction gtx = (GlobalTransaction) defaultTransactionStatus.getTransaction();
    Set<GlobalTransactionState> gtxStateSet = getGlobalTransactionStates(gtx);
    if (!gtxStateSet.contains(GlobalTransactionState.GlobalTransactionInstance)) {
        throw new TransactionSystemException(
                "Inconsistent status: defaultTransactionStatus argument is not holding "
                        + "GlobalTransaction instance.");
    }

    String gtxIdStr = gtx.getId();
    Map<String, Slim3GlobalTransactionObject> slim3GtxObjMap = slim3GtxObjMapThreadLocal.get();
    Slim3GlobalTransactionObject slim3GtxObj = slim3GtxObjMap.get(gtxIdStr);
    if (slim3GtxObj == null) {
        if (logger.isErrorEnabled()) {
            logger.error(String.format("Encountered inconsistent status: GlobalTransaction instance (ID:%1$s) "
                    + "held by defaultTransactionStatus argument is not among ones managed " + "by %2$s.",
                    gtxIdStr, this.getClass().getName()));
        }
    }

    if (!gtxStateSet.contains(GlobalTransactionState.ActiveGlobalTransaction)) {
        /* Reminder: gtx here can be inactive by the ConcurrentModificationException case. 
         * However, it's not 100% certain that, in ConcurrentModificationException case, 
         * gtx here will be always inactive.
         */

        slim3GtxObjMapThreadLocal.get().remove(gtxIdStr);

        if (logger.isWarnEnabled()) {
            logger.warn(String.format("Skipping to perform roll back on GlobalTransaction (ID:%1$s) since "
                    + "it has been already in inactive state.", gtxIdStr));
        }

        return;
    }

    if (!(gtxStateSet.contains(GlobalTransactionState.CurrentGlobalTransaction))) {
        /* Changed from throwing TransactionSystemException to logging incident in order to 
         * avoid leaving GlobalTransaction instance active as much as possible by proceeding further.
         */
        GlobalTransaction currentGtx = Datastore.getCurrentGlobalTransaction();

        if (logger.isErrorEnabled()) {
            logger.error(String.format(
                    "Encountered inconsistent status: GlobalTransaction object (ID:%1$s) held "
                            + "by defaultTransactionStatus argument is not current active GlobalTransaction "
                            + "instance (ID:%2$s).",
                    gtxIdStr, ((currentGtx instanceof GlobalTransaction) ? currentGtx.getId() : "null")));
        }
    }
    // ----------------------------------------------------------------------------------------

    try {
        if (logger.isInfoEnabled()) {
            logger.info(String.format("Rolling back on Slim3 GlobalTransaction (ID:%1$s)", gtxIdStr));
        }

        /* Note: There are the cases that GlobalTransaction instance has already been rolled back by 
         * Slim3 behind scene of Spring transaction framework when commit failed and GlobalTransaction 
         * instance remains active state. Even the control flow reached in those cases, there should be 
         * no harm being made by rolling back here again. 
         */
        gtx.rollback();
    } catch (Throwable throwable) {
        String message = String.format("Rolling back on Slim3 GlobalTransaction (ID:%1$s) failed.", gtxIdStr);
        throw new TransactionSystemException(message, throwable);
    } finally {
        slim3GtxObjMapThreadLocal.get().remove(gtxIdStr);
        /* Not necessary to call defaultTransactionStatus.setCompleted method in this block because 
         * it will be called later in cleanupAfterCompletion method.
                 defaultTransactionStatus.setCompleted();
         */
        if (gtx.isActive()) {
            if (logger.isErrorEnabled()) {
                logger.error(String.format("Slim3 GlobalTransaction (ID:%1$s) remains active "
                        + "after the attempt of rolling back.", gtxIdStr));
            }
        }
    }
}

From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManagerTest.java

/**
 * @param transactionCommited: true when committed. false for not committed, but it's not for verifying 
 * roll back./*  www.j a  va 2  s  .  co  m*/
 */
protected void verifyCommitProcess(boolean transactionCommited) {
    /* Mockito cannot spy on "final" method because it cannot mock "final" method: 
     * @see http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#13      
          mockedSlim3TxMangerInOrder.verify( slim3PlatformTransactionManager, Mockito.times( 1))
          .commit( transactionStatusArgumentCaptor.capture());
    */
    // protected boolean shouldCommitOnGlobalRollbackOnly()
    // private void processCommit(DefaultTransactionStatus status)
    // protected void prepareForCommit(DefaultTransactionStatus status)
    // protected final void triggerBeforeCommit(DefaultTransactionStatus status)
    // protected final void triggerBeforeCompletion(DefaultTransactionStatus status)
    // If it's not new transaction (means not outer most transaction), then call public final boolean isFailEarlyOnGlobalRollbackOnly()

    ArgumentCaptor<DefaultTransactionStatus> defaultTransactionStatusArgumentCaptor = ArgumentCaptor
            .forClass(DefaultTransactionStatus.class);
    if (transactionCommited) {
        mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1))
                .doCommit(defaultTransactionStatusArgumentCaptor.capture());
        DefaultTransactionStatus defaultTransactionStatus = (DefaultTransactionStatus) (defaultTransactionStatusArgumentCaptor
                .getValue());
        Assert.assertTrue(defaultTransactionStatus.isCompleted()); // should be true since actually commit has already finished
        Assert.assertTrue(defaultTransactionStatus.isNewTransaction());
        Assert.assertTrue(defaultTransactionStatus.hasTransaction());
        Assert.assertTrue(defaultTransactionStatus.getTransaction() instanceof GlobalTransaction);

        ArgumentCaptor<GlobalTransaction> globalTransactionArgumentCaptor = ArgumentCaptor
                .forClass(GlobalTransaction.class);
        mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1))
                .getGlobalTransactionStates(globalTransactionArgumentCaptor.capture());
        GlobalTransaction gtx = globalTransactionArgumentCaptor.getValue();
        Assert.assertTrue(gtx instanceof GlobalTransaction);
    } else {
        mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.never())
                .doCommit(defaultTransactionStatusArgumentCaptor.capture());
    }

    // private void triggerAfterCommit(DefaultTransactionStatus status)
    // private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus)
    // private void cleanupAfterCompletion(DefaultTransactionStatus status)
    // protected void doCleanupAfterCompletion(Object transaction)
}

From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManagerTest.java

protected void verifyRollbackProcess(boolean readOnlyEnabled, boolean roolBackOnlyEnabled,
        boolean debugEnabled) {
    // public final void rollback(TransactionStatus status)
    // private void processRollback(DefaultTransactionStatus status)
    // protected final void triggerBeforeCompletion(DefaultTransactionStatus status)

    ArgumentCaptor<DefaultTransactionStatus> defaultTransactionStatusArgumentCaptor = ArgumentCaptor
            .forClass(DefaultTransactionStatus.class);
    mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1))
            .doRollback(defaultTransactionStatusArgumentCaptor.capture());
    DefaultTransactionStatus defaultTransactionStatus = defaultTransactionStatusArgumentCaptor.getValue();
    Assert.assertTrue(defaultTransactionStatus.getTransaction() instanceof GlobalTransaction);
    GlobalTransaction gtx = (GlobalTransaction) defaultTransactionStatus.getTransaction();
    Assert.assertTrue(defaultTransactionStatus.isNewTransaction());
    Assert.assertTrue(defaultTransactionStatus.isCompleted()); // Should be true since actually transaction has already been finished
    Assert.assertEquals(readOnlyEnabled, defaultTransactionStatus.isReadOnly());
    Assert.assertEquals(roolBackOnlyEnabled, defaultTransactionStatus.isRollbackOnly());
    /* If defaultTransactionStatus.isRollbackOnly() returns true, then either 
     * its isGlobalRollbackOnly() or its isLocalRollbackOnly() returns true.
     *//*from  ww  w.ja v  a2  s. co  m*/
    if (defaultTransactionStatus.isRollbackOnly() && logger.isDebugEnabled()) {
        logger.debug("defaultTransactionStatus.isGlobalRollbackOnly() = "
                + defaultTransactionStatus.isGlobalRollbackOnly());
        logger.debug("defaultTransactionStatus.isLocalRollbackOnly() = "
                + defaultTransactionStatus.isLocalRollbackOnly());
    }
    Assert.assertEquals(debugEnabled, defaultTransactionStatus.isDebug());
    Assert.assertFalse(defaultTransactionStatus.isTransactionSavepointManager());
    Assert.assertTrue(defaultTransactionStatus.isNewSynchronization());

    mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1))
            .getGlobalTransactionStates(Mockito.eq(gtx));

    // private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus)
    // private void cleanupAfterCompletion(DefaultTransactionStatus status)
    // protected void doCleanupAfterCompletion(Object transaction)

}

From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManager.java

@Override
protected void doCommit(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException {
    GlobalTransaction gtx = (GlobalTransaction) defaultTransactionStatus.getTransaction();
    Set<GlobalTransactionState> gtxStateSet = getGlobalTransactionStates(gtx);

    // Sanity check on precondition -----------------------------------------------------------
    /*//from   w ww . java2s . com
     * This will be called at outermost transaction boundary (defaultTransactionStatus.isNewTransaction() 
     * will return true). 
     * When defaultTransactionStatus has been set for roll back, roll back doesn't need to be handled 
     * within doCommit method. 
     *    When either defaultTransactionStatus's isGlobalRollbackOnly and shouldCommitOnGlobalRollbackOnly 
     *    returns true or its isLocalRollbackOnly returns true, then logic flow won't reach here and 
     *    roll back should have been performed by doRollback.
     */
    if (defaultTransactionStatus.isRollbackOnly()) {
        throw new TransactionSystemException(String.format(
                "Unexpected system state: the transaction for the GlobalTransaction "
                        + "instance (ID:%1$s) has been marked as roll-back only "
                        + "(LocalRollbackOnly:%2$b, GlobalRollbackOnly:%3$b).",
                (gtxStateSet.contains(GlobalTransactionState.GlobalTransactionInstance) ? gtx.getId() : "null"),
                defaultTransactionStatus.isLocalRollbackOnly(),
                defaultTransactionStatus.isGlobalRollbackOnly()));
    }
    if (!defaultTransactionStatus.isNewTransaction()) {
        throw new TransactionSystemException(String.format(
                "Unexpected system state: attempted to commit from participation of an existing "
                        + "transaction (of which GlobalTransacion Id is %1$s).",
                (gtxStateSet.contains(GlobalTransactionState.GlobalTransactionInstance) ? gtx.getId()
                        : "null")));
    }
    // ----------------------------------------------------------------------------------------

    // Sanity check on gtx GlobalTransaction instance -----------------------------------------
    if (!gtxStateSet.contains(GlobalTransactionState.ActiveGlobalTransaction)) {
        String message;

        if (!gtxStateSet.contains(GlobalTransactionState.GlobalTransactionInstance)) {
            message = "Unexpected system state: The GlobalTransaction object passed as the transaction "
                    + "Object argument is null.";
        } else {
            message = String
                    .format("Unexpected system state: The GlobalTransaction instance (ID:%1$s) passed as the "
                            + "transaction Object argument is inactive.", gtx.getId());
        }

        throw new IllegalTransactionStateException(message);
    }
    if (!gtxStateSet.contains(GlobalTransactionState.CurrentGlobalTransaction)) {
        /* The one possible case of the control flow reaching here is that GlobalTransaction object 
         * is manually instantiated at the outside of Spring transaction framework, and it is left active.
         * 
         * In nesting global transaction, easy to yield ConcurrentModificationException without care.
         * Nesting global transaction should be less necessary, since Slim3 isolate between (Global) 
         * transactions and cannot change that isolation setting, and this uses Slim3 GlobalTransaction, 
         * as GAE/J datastore API is not provide suspend feature as well.
         */

        GlobalTransaction currentGtx = Datastore.getCurrentGlobalTransaction();
        if (logger.isWarnEnabled()) {
            logger.warn(String.format(
                    "Though active GlobalTransaction instance (ID:%1$s) is passed as transaction "
                            + "Object argument, it's not current GlobalTransaction instance (ID:%2$s).",
                    gtx.getId(), ((currentGtx instanceof GlobalTransaction) ? currentGtx.getId() : "null")));
        }
    }
    // ----------------------------------------------------------------------------------------
    boolean exceptionUp = false;
    try {
        gtx.commit();
        slim3GtxObjMapThreadLocal.get().remove(gtx.getId());
        if (logger.isInfoEnabled()) {
            logger.info(String.format("Slim3 GlobalTransaction (ID:%1$s) committed.", gtx.getId()));
        }
    } catch (Throwable throwable) {
        /* Set rollback only flag so calling processRollback method to roll back will occur at 
         * commit method by AnnotationTransactionAspect, even for other exceptions than ones specified 
         * for rollbackFor or rollbackForClassname attributes of @Transactional annotation.
         */
        defaultTransactionStatus.setRollbackOnly();

        exceptionUp = true;

        String message = String.format("Slim3 GlobalTransaction (ID:%1$s) failed on commit.", gtx.getId());
        if ((throwable instanceof ConcurrentModificationException)
                || (throwable instanceof DeadlineExceededException)) {
            /* Slim3 should have already rolled back automatically on either
             * ConcurrentModificationException or DeadlineExceededException.
             * 
             * About DeadlineExceededException case: It seems like no harm
             * will be made even active global transaction at
             * DeadlineExceededException case left behind. As looking
             * briefly through the Slim3 source codes, the locks by that
             * global transaction seems to be released while it rolls back
             * by DatastoreFilter, and itself seem to be removed from
             * TheadLocal stack of the global transactions. So, it won't be
             * returned by such Datastore.getCurrentGlobalTransaction()
             * method. See at
             * http://groups.google.com/group/slim3-user/browse_frm
             * /thread/e3d47d8f28c8e8d3
             * /9e43553f3b56d1f2?tvc=1#9e43553f3b56d1f2 If it turns out
             * opposite, then that active global transaction can be cleared
             * some how at here for DeadlineExceededException case.
             */

            message = String.format("Slim3 GlobalTransaction (ID:%1$s) failed on commit. %n"
                    + "Slim3 must have already rolled back automatically behind "
                    + "Spring transaction framework.", gtx.getId());
        }

        throw new TransactionSystemException(message, throwable);
    } finally {
        if (gtx.isActive()) {
            if (exceptionUp) {
                if (logger.isInfoEnabled()) {
                    logger.info(String.format(
                            "GlobalTransaction instance (ID:%1$s) remains active after exception "
                                    + "durring commit attempt. That GlobalTransaction instance has not "
                                    + "been removed yet from slim3GtxObjMapThreadLocal member field.",
                            gtx.getId(), this.getClass().getName()));
                }
            } else {
                if (logger.isWarnEnabled()) {
                    logger.warn(String.format(
                            "Unexpected system state: GlobalTransaction instance (ID:%1$s) "
                                    + "remains active even after commit attempt. That GlobalTransaction "
                                    + "instance was removed from slim3GtxObjMapThreadLocal member field.",
                            gtx.getId(), this.getClass().getName()));
                }
            }
        }
    }
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * Process an actual commit.//from   w  ww .  j  ava 2  s .c o m
 * Rollback-only flags have already been checked and applied.
 * @param status object representing the transaction
 * @throws TransactionException in case of commit failure
 */
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;

        try {
            boolean unexpectedRollback = false;
            prepareForCommit(status);
            triggerBeforeCommit(status);
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;

            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    logger.debug("Releasing transaction savepoint");
                }
                unexpectedRollback = status.isGlobalRollbackOnly();
                status.releaseHeldSavepoint();
            } else if (status.isNewTransaction()) {
                if (status.isDebug()) {
                    logger.debug("Initiating transaction commit");
                }
                unexpectedRollback = status.isGlobalRollbackOnly();
                doCommit(status);
            } else if (isFailEarlyOnGlobalRollbackOnly()) {
                unexpectedRollback = status.isGlobalRollbackOnly();
            }

            // Throw UnexpectedRollbackException if we have a global rollback-only
            // marker but still didn't get a corresponding exception from commit.
            if (unexpectedRollback) {
                throw new UnexpectedRollbackException(
                        "Transaction silently rolled back because it has been marked as rollback-only");
            }
        } catch (UnexpectedRollbackException ex) {
            // can only be caused by doCommit
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
            throw ex;
        } catch (TransactionException ex) {
            // can only be caused by doCommit
            if (isRollbackOnCommitFailure()) {
                doRollbackOnCommitException(status, ex);
            } else {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            }
            throw ex;
        } catch (RuntimeException | Error ex) {
            if (!beforeCompletionInvoked) {
                triggerBeforeCompletion(status);
            }
            doRollbackOnCommitException(status, ex);
            throw ex;
        }

        // Trigger afterCommit callbacks, with an exception thrown there
        // propagated to callers but the transaction still considered as committed.
        try {
            triggerAfterCommit(status);
        } finally {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
        }

    } finally {
        cleanupAfterCompletion(status);
    }
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * Process an actual rollback.//from w  w  w.ja v  a 2  s .  c o m
 * The completed flag has already been checked.
 * @param status object representing the transaction
 * @throws TransactionException in case of rollback failure
 */
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
    try {
        boolean unexpectedRollback = unexpected;

        try {
            triggerBeforeCompletion(status);

            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    logger.debug("Rolling back transaction to savepoint");
                }
                status.rollbackToHeldSavepoint();
            } else if (status.isNewTransaction()) {
                if (status.isDebug()) {
                    logger.debug("Initiating transaction rollback");
                }
                doRollback(status);
            } else {
                // Participating in larger transaction
                if (status.hasTransaction()) {
                    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                        if (status.isDebug()) {
                            logger.debug(
                                    "Participating transaction failed - marking existing transaction as rollback-only");
                        }
                        doSetRollbackOnly(status);
                    } else {
                        if (status.isDebug()) {
                            logger.debug(
                                    "Participating transaction failed - letting transaction originator decide on rollback");
                        }
                    }
                } else {
                    logger.debug("Should roll back transaction but cannot - no transaction available");
                }
                // Unexpected rollback only matters here if we're asked to fail early
                if (!isFailEarlyOnGlobalRollbackOnly()) {
                    unexpectedRollback = false;
                }
            }
        } catch (RuntimeException | Error ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
        }

        triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

        // Raise UnexpectedRollbackException if we had a global rollback-only marker
        if (unexpectedRollback) {
            throw new UnexpectedRollbackException(
                    "Transaction rolled back because it has been marked as rollback-only");
        }
    } finally {
        cleanupAfterCompletion(status);
    }
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * Invoke {@code doRollback}, handling rollback exceptions properly.
 * @param status object representing the transaction
 * @param ex the thrown application exception or error
 * @throws TransactionException in case of rollback failure
 * @see #doRollback// w ww  . ja  va 2s.c o m
 */
private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex)
        throws TransactionException {
    try {
        if (status.isNewTransaction()) {
            if (status.isDebug()) {
                logger.debug("Initiating transaction rollback after commit exception", ex);
            }
            doRollback(status);
        } else if (status.hasTransaction() && isGlobalRollbackOnParticipationFailure()) {
            if (status.isDebug()) {
                logger.debug("Marking existing transaction as rollback-only after commit exception", ex);
            }
            doSetRollbackOnly(status);
        }
    } catch (RuntimeException | Error rbex) {
        logger.error("Commit exception overridden by rollback exception", ex);
        triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
        throw rbex;
    }
    triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * Trigger {@code afterCompletion} callbacks.
 * @param status object representing the transaction
 * @param completionStatus completion status according to TransactionSynchronization constants
 *///from   w w  w  .ja  v  a 2 s . com
private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
    if (status.isNewSynchronization()) {
        List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager
                .getSynchronizations();
        TransactionSynchronizationManager.clearSynchronization();
        if (!status.hasTransaction() || status.isNewTransaction()) {
            if (status.isDebug()) {
                logger.trace("Triggering afterCompletion synchronization");
            }
            // No transaction or new transaction for the current scope ->
            // invoke the afterCompletion callbacks immediately
            invokeAfterCompletion(synchronizations, completionStatus);
        } else if (!synchronizations.isEmpty()) {
            // Existing transaction that we participate in, controlled outside
            // of the scope of this Spring transaction manager -> try to register
            // an afterCompletion callback with the existing (JTA) transaction.
            registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
        }
    }
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * Clean up after completion, clearing synchronization if necessary,
 * and invoking doCleanupAfterCompletion.
 * @param status object representing the transaction
 * @see #doCleanupAfterCompletion// www  . ja  v  a 2  s  .  co  m
 */
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
    status.setCompleted();
    if (status.isNewSynchronization()) {
        TransactionSynchronizationManager.clear();
    }
    if (status.isNewTransaction()) {
        doCleanupAfterCompletion(status.getTransaction());
    }
    if (status.getSuspendedResources() != null) {
        if (status.isDebug()) {
            logger.debug("Resuming suspended transaction after completion of inner transaction");
        }
        Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
        resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
    }
}