Search in sources :

Example 6 with IllegalTransactionStateException

use of org.springframework.transaction.IllegalTransactionStateException in project spring-framework by spring-projects.

the class WebSphereUowTransactionManagerTests method propagationMandatoryFailsInCaseOfNoExistingTransaction.

@Test
public void propagationMandatoryFailsInCaseOfNoExistingTransaction() {
    MockUOWManager manager = new MockUOWManager();
    WebSphereUowTransactionManager ptm = new WebSphereUowTransactionManager(manager);
    DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
    definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY);
    try {
        ptm.execute(definition, new TransactionCallback<String>() {

            @Override
            public String doInTransaction(TransactionStatus status) {
                return "result";
            }
        });
        fail("Should have thrown IllegalTransactionStateException");
    } catch (IllegalTransactionStateException ex) {
    // expected
    }
}
Also used : DefaultTransactionDefinition(org.springframework.transaction.support.DefaultTransactionDefinition) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException) TransactionStatus(org.springframework.transaction.TransactionStatus) Test(org.junit.Test)

Example 7 with IllegalTransactionStateException

use of org.springframework.transaction.IllegalTransactionStateException in project spring-framework by spring-projects.

the class AbstractReactiveTransactionManager method getReactiveTransaction.

// ---------------------------------------------------------------------
// Implementation of ReactiveTransactionManager
// ---------------------------------------------------------------------
/**
 * This implementation handles propagation behavior. Delegates to
 * {@code doGetTransaction}, {@code isExistingTransaction}
 * and {@code doBegin}.
 * @see #doGetTransaction
 * @see #isExistingTransaction
 * @see #doBegin
 */
@Override
public final Mono<ReactiveTransaction> getReactiveTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
    // Use defaults if no transaction definition given.
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
    return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> {
        Object transaction = doGetTransaction(synchronizationManager);
        // Cache debug flag to avoid repeated checks.
        boolean debugEnabled = logger.isDebugEnabled();
        if (isExistingTransaction(transaction)) {
            // Existing transaction found -> check propagation behavior to find out how to behave.
            return handleExistingTransaction(synchronizationManager, def, transaction, debugEnabled);
        }
        // Check definition settings for new transaction.
        if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
            return Mono.error(new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout()));
        }
        // No existing transaction found -> check propagation behavior to find out how to proceed.
        if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
            return Mono.error(new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'"));
        } else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
            return TransactionContextManager.currentContext().map(TransactionSynchronizationManager::new).flatMap(nestedSynchronizationManager -> suspend(nestedSynchronizationManager, null).map(Optional::of).defaultIfEmpty(Optional.empty()).flatMap(suspendedResources -> {
                if (debugEnabled) {
                    logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
                }
                return Mono.defer(() -> {
                    GenericReactiveTransaction status = newReactiveTransaction(nestedSynchronizationManager, def, transaction, true, debugEnabled, suspendedResources.orElse(null));
                    return doBegin(nestedSynchronizationManager, transaction, def).doOnSuccess(ignore -> prepareSynchronization(nestedSynchronizationManager, status, def)).thenReturn(status);
                }).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR, ex -> resume(nestedSynchronizationManager, null, suspendedResources.orElse(null)).then(Mono.error(ex)));
            }));
        } else {
            // Create "empty" transaction: no actual transaction, but potentially synchronization.
            if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
                logger.warn("Custom isolation level specified but no actual transaction initiated; " + "isolation level will effectively be ignored: " + def);
            }
            return Mono.just(prepareReactiveTransaction(synchronizationManager, def, null, true, debugEnabled, null));
        }
    });
}
Also used : TransactionDefinition(org.springframework.transaction.TransactionDefinition) TransactionSuspensionNotSupportedException(org.springframework.transaction.TransactionSuspensionNotSupportedException) Predicate(java.util.function.Predicate) TransactionDefinition(org.springframework.transaction.TransactionDefinition) ObjectInputStream(java.io.ObjectInputStream) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) IOException(java.io.IOException) Mono(reactor.core.publisher.Mono) UnexpectedRollbackException(org.springframework.transaction.UnexpectedRollbackException) ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) Serializable(java.io.Serializable) Flux(reactor.core.publisher.Flux) List(java.util.List) InvalidTimeoutException(org.springframework.transaction.InvalidTimeoutException) TransactionException(org.springframework.transaction.TransactionException) Optional(java.util.Optional) Log(org.apache.commons.logging.Log) Nullable(org.springframework.lang.Nullable) LogFactory(org.apache.commons.logging.LogFactory) InvalidTimeoutException(org.springframework.transaction.InvalidTimeoutException) Optional(java.util.Optional) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException)

Example 8 with IllegalTransactionStateException

use of org.springframework.transaction.IllegalTransactionStateException in project spring-framework by spring-projects.

the class AbstractPlatformTransactionManager method getTransaction.

// ---------------------------------------------------------------------
// Implementation of PlatformTransactionManager
// ---------------------------------------------------------------------
/**
 * This implementation handles propagation behavior. Delegates to
 * {@code doGetTransaction}, {@code isExistingTransaction}
 * and {@code doBegin}.
 * @see #doGetTransaction
 * @see #isExistingTransaction
 * @see #doBegin
 */
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
    // Use defaults if no transaction definition given.
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
    Object transaction = doGetTransaction();
    boolean debugEnabled = logger.isDebugEnabled();
    if (isExistingTransaction(transaction)) {
        // Existing transaction found -> check propagation behavior to find out how to behave.
        return handleExistingTransaction(def, transaction, debugEnabled);
    }
    // Check definition settings for new transaction.
    if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
    }
    // No existing transaction found -> check propagation behavior to find out how to proceed.
    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
    } else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        SuspendedResourcesHolder suspendedResources = suspend(null);
        if (debugEnabled) {
            logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
        }
        try {
            return startTransaction(def, transaction, debugEnabled, suspendedResources);
        } catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    } else {
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; " + "isolation level will effectively be ignored: " + def);
        }
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    }
}
Also used : TransactionDefinition(org.springframework.transaction.TransactionDefinition) InvalidTimeoutException(org.springframework.transaction.InvalidTimeoutException) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException)

Example 9 with IllegalTransactionStateException

use of org.springframework.transaction.IllegalTransactionStateException in project spring-framework by spring-projects.

the class AbstractPlatformTransactionManager method handleExistingTransaction.

/**
 * Create a TransactionStatus for an existing transaction.
 */
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
        throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");
    }
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction");
        }
        Object suspendedResources = suspend(transaction);
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction, creating new transaction with name [" + definition.getName() + "]");
        }
        SuspendedResourcesHolder suspendedResources = suspend(transaction);
        try {
            return startTransaction(definition, transaction, debugEnabled, suspendedResources);
        } catch (RuntimeException | Error beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
    }
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        if (!isNestedTransactionAllowed()) {
            throw new NestedTransactionNotSupportedException("Transaction manager does not allow nested transactions by default - " + "specify 'nestedTransactionAllowed' property with value 'true'");
        }
        if (debugEnabled) {
            logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
        }
        if (useSavepointForNestedTransaction()) {
            // Create savepoint within existing Spring-managed transaction,
            // through the SavepointManager API implemented by TransactionStatus.
            // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
            DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
            status.createAndHoldSavepoint();
            return status;
        } else {
            // in case of a pre-existing JTA transaction.
            return startTransaction(definition, transaction, debugEnabled, null);
        }
    }
    // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
    if (debugEnabled) {
        logger.debug("Participating in existing transaction");
    }
    if (isValidateExistingTransaction()) {
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
                Constants isoConstants = DefaultTransactionDefinition.constants;
                throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));
            }
        }
        if (!definition.isReadOnly()) {
            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is");
            }
        }
    }
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
Also used : NestedTransactionNotSupportedException(org.springframework.transaction.NestedTransactionNotSupportedException) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException) Constants(org.springframework.core.Constants)

Example 10 with IllegalTransactionStateException

use of org.springframework.transaction.IllegalTransactionStateException in project spring-framework by spring-projects.

the class JdbcTransactionManagerTests method testPropagationNeverWithExistingTransaction.

@Test
public void testPropagationNeverWithExistingTransaction() throws Exception {
    final TransactionTemplate tt = new TransactionTemplate(tm);
    tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    boolean condition2 = !TransactionSynchronizationManager.hasResource(ds);
    assertThat(condition2).as("Hasn't thread connection").isTrue();
    boolean condition1 = !TransactionSynchronizationManager.isSynchronizationActive();
    assertThat(condition1).as("Synchronization not active").isTrue();
    assertThatExceptionOfType(IllegalTransactionStateException.class).isThrownBy(() -> tt.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
            assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
            tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER);
            tt.execute(new TransactionCallbackWithoutResult() {

                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
                    fail("Should have thrown IllegalTransactionStateException");
                }
            });
            fail("Should have thrown IllegalTransactionStateException");
        }
    }));
    boolean condition = !TransactionSynchronizationManager.hasResource(ds);
    assertThat(condition).as("Hasn't thread connection").isTrue();
    verify(con).rollback();
    verify(con).close();
}
Also used : TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) IllegalTransactionStateException(org.springframework.transaction.IllegalTransactionStateException) TransactionStatus(org.springframework.transaction.TransactionStatus) TransactionCallbackWithoutResult(org.springframework.transaction.support.TransactionCallbackWithoutResult) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

IllegalTransactionStateException (org.springframework.transaction.IllegalTransactionStateException)10 TransactionStatus (org.springframework.transaction.TransactionStatus)4 InvalidTimeoutException (org.springframework.transaction.InvalidTimeoutException)3 DefaultTransactionDefinition (org.springframework.transaction.support.DefaultTransactionDefinition)3 Test (org.junit.Test)2 Test (org.junit.jupiter.api.Test)2 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)2 ConnectionHolder (org.springframework.jdbc.datasource.ConnectionHolder)2 CannotCreateTransactionException (org.springframework.transaction.CannotCreateTransactionException)2 NestedTransactionNotSupportedException (org.springframework.transaction.NestedTransactionNotSupportedException)2 TransactionDefinition (org.springframework.transaction.TransactionDefinition)2 TransactionException (org.springframework.transaction.TransactionException)2 TransactionCallbackWithoutResult (org.springframework.transaction.support.TransactionCallbackWithoutResult)2 TransactionTemplate (org.springframework.transaction.support.TransactionTemplate)2 UOWActionException (com.ibm.wsspi.uow.UOWActionException)1 UOWException (com.ibm.wsspi.uow.UOWException)1 IOException (java.io.IOException)1 ObjectInputStream (java.io.ObjectInputStream)1 Serializable (java.io.Serializable)1 Connection (java.sql.Connection)1