Search in sources :

Example 1 with ReactiveTransaction

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

the class AbstractReactiveTransactionAspectTests method transactionShouldSucceedWithNotNew.

/**
 * Check that a transaction is created and committed.
 */
@Test
public void transactionShouldSucceedWithNotNew() throws Exception {
    TransactionAttribute txatt = new DefaultTransactionAttribute();
    MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
    tas.register(getNameMethod, txatt);
    ReactiveTransaction status = mock(ReactiveTransaction.class);
    ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
    // expect a transaction
    given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
    given(rtm.commit(status)).willReturn(Mono.empty());
    DefaultTestBean tb = new DefaultTestBean();
    TestBean itb = (TestBean) advised(tb, rtm, tas);
    itb.getName().as(StepVerifier::create).verifyComplete();
    verify(rtm).commit(status);
}
Also used : ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) Test(org.junit.jupiter.api.Test)

Example 2 with ReactiveTransaction

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

the class AbstractReactiveTransactionAspectTests method twoTransactionsShouldSucceed.

/**
 * Check that two transactions are created and committed.
 */
@Test
public void twoTransactionsShouldSucceed() throws Exception {
    TransactionAttribute txatt = new DefaultTransactionAttribute();
    MapTransactionAttributeSource tas1 = new MapTransactionAttributeSource();
    tas1.register(getNameMethod, txatt);
    MapTransactionAttributeSource tas2 = new MapTransactionAttributeSource();
    tas2.register(setNameMethod, txatt);
    ReactiveTransaction status = mock(ReactiveTransaction.class);
    ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
    // expect a transaction
    given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
    given(rtm.commit(status)).willReturn(Mono.empty());
    DefaultTestBean tb = new DefaultTestBean();
    TestBean itb = (TestBean) advised(tb, rtm, new TransactionAttributeSource[] { tas1, tas2 });
    itb.getName().as(StepVerifier::create).verifyComplete();
    Mono.from(itb.setName("myName")).as(StepVerifier::create).verifyComplete();
    verify(rtm, times(2)).commit(status);
}
Also used : ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) Test(org.junit.jupiter.api.Test)

Example 3 with ReactiveTransaction

use of org.springframework.transaction.ReactiveTransaction 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 4 with ReactiveTransaction

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

the class AbstractReactiveTransactionAspectTests method cannotCommitTransaction.

/**
 * Simulate failure of the underlying transaction infrastructure to commit.
 * Check that the target method was invoked, but that the transaction
 * infrastructure exception was thrown to the client
 */
@Test
public void cannotCommitTransaction() throws Exception {
    TransactionAttribute txatt = new DefaultTransactionAttribute();
    Method m = setNameMethod;
    MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
    tas.register(m, txatt);
    // Method m2 = getNameMethod;
    // No attributes for m2
    ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
    ReactiveTransaction status = mock(ReactiveTransaction.class);
    given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
    UnexpectedRollbackException ex = new UnexpectedRollbackException("foobar", null);
    given(rtm.commit(status)).willReturn(Mono.error(ex));
    given(rtm.rollback(status)).willReturn(Mono.empty());
    DefaultTestBean tb = new DefaultTestBean();
    TestBean itb = (TestBean) advised(tb, rtm, tas);
    String name = "new name";
    Mono.from(itb.setName(name)).as(StepVerifier::create).consumeErrorWith(throwable -> {
        assertThat(throwable.getClass()).isEqualTo(RuntimeException.class);
        assertThat(throwable.getCause()).isEqualTo(ex);
    }).verify();
    // Should have invoked target and changed name
    itb.getName().as(StepVerifier::create).expectNext(name).verifyComplete();
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) StepVerifier(reactor.test.StepVerifier) Publisher(org.reactivestreams.Publisher) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Mono(reactor.core.publisher.Mono) UnexpectedRollbackException(org.springframework.transaction.UnexpectedRollbackException) Mockito.times(org.mockito.Mockito.times) ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) Fail.fail(org.assertj.core.api.Fail.fail) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) Mockito.verify(org.mockito.Mockito.verify) Mockito.verifyNoInteractions(org.mockito.Mockito.verifyNoInteractions) Test(org.junit.jupiter.api.Test) TransactionSystemException(org.springframework.transaction.TransactionSystemException) BDDMockito.given(org.mockito.BDDMockito.given) TransactionContext(org.springframework.transaction.reactive.TransactionContext) CannotCreateTransactionException(org.springframework.transaction.CannotCreateTransactionException) Method(java.lang.reflect.Method) Mockito.mock(org.mockito.Mockito.mock) Method(java.lang.reflect.Method) ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) UnexpectedRollbackException(org.springframework.transaction.UnexpectedRollbackException) StepVerifier(reactor.test.StepVerifier) Test(org.junit.jupiter.api.Test)

Example 5 with ReactiveTransaction

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

the class AbstractReactiveTransactionAspectTests method transactionShouldSucceed.

/**
 * Check that a transaction is created and committed.
 */
@Test
public void transactionShouldSucceed() throws Exception {
    TransactionAttribute txatt = new DefaultTransactionAttribute();
    MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
    tas.register(getNameMethod, txatt);
    ReactiveTransaction status = mock(ReactiveTransaction.class);
    ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
    // expect a transaction
    given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
    given(rtm.commit(status)).willReturn(Mono.empty());
    DefaultTestBean tb = new DefaultTestBean();
    TestBean itb = (TestBean) advised(tb, rtm, tas);
    itb.getName().as(StepVerifier::create).verifyComplete();
    verify(rtm).commit(status);
}
Also used : ReactiveTransaction(org.springframework.transaction.ReactiveTransaction) ReactiveTransactionManager(org.springframework.transaction.ReactiveTransactionManager) Test(org.junit.jupiter.api.Test)

Aggregations

ReactiveTransaction (org.springframework.transaction.ReactiveTransaction)6 ReactiveTransactionManager (org.springframework.transaction.ReactiveTransactionManager)6 Test (org.junit.jupiter.api.Test)5 UnexpectedRollbackException (org.springframework.transaction.UnexpectedRollbackException)3 Mono (reactor.core.publisher.Mono)3 Method (java.lang.reflect.Method)2 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)2 Fail.fail (org.assertj.core.api.Fail.fail)2 BeforeEach (org.junit.jupiter.api.BeforeEach)2 BDDMockito.given (org.mockito.BDDMockito.given)2 Mockito.mock (org.mockito.Mockito.mock)2 Mockito.times (org.mockito.Mockito.times)2 Mockito.verify (org.mockito.Mockito.verify)2 Mockito.verifyNoInteractions (org.mockito.Mockito.verifyNoInteractions)2 Publisher (org.reactivestreams.Publisher)2 CannotCreateTransactionException (org.springframework.transaction.CannotCreateTransactionException)2 TransactionSystemException (org.springframework.transaction.TransactionSystemException)2 TransactionContext (org.springframework.transaction.reactive.TransactionContext)2 StepVerifier (reactor.test.StepVerifier)2 IOException (java.io.IOException)1