Example usage for org.springframework.transaction.reactive TransactionContextManager currentContext

List of usage examples for org.springframework.transaction.reactive TransactionContextManager currentContext

Introduction

In this page you can find the example usage for org.springframework.transaction.reactive TransactionContextManager currentContext.

Prototype

public static Mono<TransactionContext> currentContext() throws NoTransactionException 

Source Link

Document

Obtain the current TransactionContext from the subscriber context or the transactional context holder.

Usage

From source file:org.springframework.transaction.reactive.AbstractReactiveTransactionManager.java

/**
 * This implementation handles propagation behavior. Delegates to
 * {@code doGetTransaction}, {@code isExistingTransaction}
 * and {@code doBegin}.// w w  w.ja  va2 s  .c  o m
 * @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.currentTransaction().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));
        }
    });
}

From source file:org.springframework.transaction.reactive.TransactionalOperatorImpl.java

@Override
public <T> Flux<T> execute(TransactionCallback<T> action) throws TransactionException {
    return TransactionContextManager.currentContext().flatMapMany(context -> {
        Mono<ReactiveTransaction> status = this.transactionManager
                .getReactiveTransaction(this.transactionDefinition);
        // This is an around advice: Invoke the next interceptor in the chain.
        // This will normally result in a target object being invoked.
        // Need re-wrapping of ReactiveTransaction until we get hold of the exception
        // through usingWhen.
        return status.flatMapMany(it -> Flux
                .usingWhen(Mono.just(it), action::doInTransaction, this.transactionManager::commit,
                        s -> Mono.empty())
                .onErrorResume(ex -> rollbackOnException(it, ex).then(Mono.error(ex))));
    }).subscriberContext(TransactionContextManager.getOrCreateContext())
            .subscriberContext(TransactionContextManager.getOrCreateContextHolder());
}

From source file:org.springframework.transaction.reactive.TransactionSynchronizationManager.java

/**
 * Return the TransactionSynchronizationManager of the current transaction.
 * Mainly intended for code that wants to bind resources or synchronizations.
 * rollback-only but not throw an application exception.
 * @throws NoTransactionException if the transaction info cannot be found,
 * because the method was invoked outside a managed transaction.
 *///from  ww w  . j  a v  a  2s.com
public static Mono<TransactionSynchronizationManager> currentTransaction() {
    return TransactionContextManager.currentContext().map(TransactionSynchronizationManager::new);
}