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

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

Introduction

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

Prototype

@Override
public boolean isGlobalRollbackOnly() 

Source Link

Document

Determine the rollback-only flag via checking the transaction object, provided that the latter implements the SmartTransactionObject interface.

Usage

From source file:org.ujorm.orm.support.UjormTransactionManager.java

@Override
protected void doCommit(DefaultTransactionStatus dts) throws TransactionException {
    dts.isGlobalRollbackOnly();
    if (decCalling()) {
        LOGGER.log(UjoLogger.TRACE, "Auto transaction ending (commit/rollback)");

        if (ujoSessionFactory.getDefaultSession().isRollbackOnly()) {
            LOGGER.log(UjoLogger.WARN, "Rolling back transaction becaouse has been mark as roll back only");
            rollback(dts);//from  ww w  .  j  av  a 2s.c  om
            return;
        }
        LOGGER.log(UjoLogger.INFO, "commiting transaction ...");
        ujoSessionFactory.getDefaultSession().commitTransaction();
    }
}

From source file:org.ujorm.spring.UjormTransactionManager.java

/** Perform an actual commit of the given transaction. */
@Override/*w ww .j a  v  a2s  . c  om*/
protected void doCommit(DefaultTransactionStatus dts) throws TransactionException {
    final Session localSession = getLocalSession();
    final boolean rollbackOnly = dts.isGlobalRollbackOnly() || localSession.isRollbackOnly();
    if (rollbackOnly) {
        LOGGER.log(UjoLogger.WARN, "Rolling back transaction becaouse has been mark as roll back only");
    }
    doEnd(!rollbackOnly, localSession);
}

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   w w w.j av a 2  s.c o 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  www  .j ava 2s .  co m*/
     * 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

/**
 * This implementation of commit handles participating in existing
 * transactions and programmatic rollback requests.
 * Delegates to {@code isRollbackOnly}, {@code doCommit}
 * and {@code rollback}./*from   www . j a va2 s.  c  o  m*/
 * @see org.springframework.transaction.TransactionStatus#isRollbackOnly()
 * @see #doCommit
 * @see #rollback
 */
@Override
public final void commit(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {
        throw new IllegalTransactionStateException(
                "Transaction is already completed - do not call commit or rollback more than once per transaction");
    }

    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    if (defStatus.isLocalRollbackOnly()) {
        if (defStatus.isDebug()) {
            logger.debug("Transactional code has requested rollback");
        }
        processRollback(defStatus, false);
        return;
    }

    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
        if (defStatus.isDebug()) {
            logger.debug(
                    "Global transaction is marked as rollback-only but transactional code requested commit");
        }
        processRollback(defStatus, true);
        return;
    }

    processCommit(defStatus);
}

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

/**
 * Process an actual commit./*w w w  .  ja v  a2 s .c  om*/
 * 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);
    }
}