Search in sources :

Example 1 with CallbackPreferringPlatformTransactionManager

use of cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager in project today-framework by TAKETODAY.

the class TransactionAspectSupport method invokeWithinTransaction.

/**
 * General delegate for around-advice-based subclasses, delegating to several other template
 * methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
 * as well as regular {@link PlatformTransactionManager} implementations and
 * {@link ReactiveTransactionManager} implementations for reactive return types.
 *
 * @param method the Method being invoked
 * @param targetClass the target class that we're invoking the method on
 * @param invocation the callback to use for proceeding with the target invocation
 * @return the return value of the method, if any
 * @throws Throwable propagated from the target invocation
 */
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
    // If the transaction attribute is null, the method is non-transactional.
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
    final TransactionManager tm = determineTransactionManager(txAttr);
    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
        ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
            Class<?> reactiveType = method.getReturnType();
            ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
            if (adapter == null) {
                throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
            }
            return new ReactiveTransactionSupport(adapter);
        });
        return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
    }
    PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
        // Standard transaction demarcation with getTransaction and commit/rollback calls.
        TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
        Object retVal;
        try {
            // This is an around advice: Invoke the next interceptor in the chain.
            // This will normally result in a target object being invoked.
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable ex) {
            // target invocation exception
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            cleanupTransactionInfo(txInfo);
        }
        commitTransactionAfterReturning(txInfo);
        return retVal;
    } else {
        Object result;
        ThrowableHolder throwableHolder = new ThrowableHolder();
        // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
        try {
            result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
                TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
                try {
                    return invocation.proceedWithInvocation();
                } catch (Throwable ex) {
                    if (txAttr.rollbackOn(ex)) {
                        // A RuntimeException: will lead to a rollback.
                        if (ex instanceof RuntimeException) {
                            throw (RuntimeException) ex;
                        } else {
                            throw new ThrowableHolderException(ex);
                        }
                    } else {
                        // A normal return value: will lead to a commit.
                        throwableHolder.throwable = ex;
                        return null;
                    }
                } finally {
                    cleanupTransactionInfo(txInfo);
                }
            });
        } catch (ThrowableHolderException ex) {
            throw ex.getCause();
        } catch (TransactionSystemException ex2) {
            if (throwableHolder.throwable != null) {
                log.error("Application exception overridden by commit exception", throwableHolder.throwable);
                ex2.initApplicationException(throwableHolder.throwable);
            }
            throw ex2;
        } catch (Throwable ex2) {
            if (throwableHolder.throwable != null) {
                log.error("Application exception overridden by commit exception", throwableHolder.throwable);
            }
            throw ex2;
        }
        // Check result state: It might indicate a Throwable to rethrow.
        if (throwableHolder.throwable != null) {
            throw throwableHolder.throwable;
        }
        return result;
    }
}
Also used : StringUtils(cn.taketoday.util.StringUtils) Assert(cn.taketoday.lang.Assert) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) NoTransactionException(cn.taketoday.transaction.NoTransactionException) TransactionManager(cn.taketoday.transaction.TransactionManager) ClassUtils(cn.taketoday.util.ClassUtils) TransactionStatus(cn.taketoday.transaction.TransactionStatus) TransactionContextManager(cn.taketoday.transaction.reactive.TransactionContextManager) ConcurrentMap(java.util.concurrent.ConcurrentMap) Method(java.lang.reflect.Method) ReactiveTransaction(cn.taketoday.transaction.ReactiveTransaction) Properties(java.util.Properties) BeanFactoryAware(cn.taketoday.beans.factory.BeanFactoryAware) NamedThreadLocal(cn.taketoday.core.NamedThreadLocal) ConcurrentReferenceHashMap(cn.taketoday.util.ConcurrentReferenceHashMap) ReactiveAdapterRegistry(cn.taketoday.core.ReactiveAdapterRegistry) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) BeanFactory(cn.taketoday.beans.factory.BeanFactory) Mono(reactor.core.publisher.Mono) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) LoggerFactory(cn.taketoday.logging.LoggerFactory) Flux(reactor.core.publisher.Flux) BeanFactoryAnnotationUtils(cn.taketoday.beans.factory.annotation.BeanFactoryAnnotationUtils) ReactiveAdapter(cn.taketoday.core.ReactiveAdapter) Nullable(cn.taketoday.lang.Nullable) TransactionSystemException(cn.taketoday.transaction.TransactionSystemException) Logger(cn.taketoday.logging.Logger) InitializingBean(cn.taketoday.beans.factory.InitializingBean) TransactionSystemException(cn.taketoday.transaction.TransactionSystemException) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) TransactionManager(cn.taketoday.transaction.TransactionManager) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) ReactiveAdapter(cn.taketoday.core.ReactiveAdapter) Nullable(cn.taketoday.lang.Nullable)

Example 2 with CallbackPreferringPlatformTransactionManager

use of cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager in project today-infrastructure by TAKETODAY.

the class TransactionAspectSupport method invokeWithinTransaction.

/**
 * General delegate for around-advice-based subclasses, delegating to several other template
 * methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
 * as well as regular {@link PlatformTransactionManager} implementations and
 * {@link ReactiveTransactionManager} implementations for reactive return types.
 *
 * @param method the Method being invoked
 * @param targetClass the target class that we're invoking the method on
 * @param invocation the callback to use for proceeding with the target invocation
 * @return the return value of the method, if any
 * @throws Throwable propagated from the target invocation
 */
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
    // If the transaction attribute is null, the method is non-transactional.
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
    final TransactionManager tm = determineTransactionManager(txAttr);
    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
        ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
            Class<?> reactiveType = method.getReturnType();
            ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
            if (adapter == null) {
                throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
            }
            return new ReactiveTransactionSupport(adapter);
        });
        return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
    }
    PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
        // Standard transaction demarcation with getTransaction and commit/rollback calls.
        TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
        Object retVal;
        try {
            // This is an around advice: Invoke the next interceptor in the chain.
            // This will normally result in a target object being invoked.
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable ex) {
            // target invocation exception
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            cleanupTransactionInfo(txInfo);
        }
        commitTransactionAfterReturning(txInfo);
        return retVal;
    } else {
        Object result;
        ThrowableHolder throwableHolder = new ThrowableHolder();
        // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
        try {
            result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
                TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
                try {
                    return invocation.proceedWithInvocation();
                } catch (Throwable ex) {
                    if (txAttr.rollbackOn(ex)) {
                        // A RuntimeException: will lead to a rollback.
                        if (ex instanceof RuntimeException) {
                            throw (RuntimeException) ex;
                        } else {
                            throw new ThrowableHolderException(ex);
                        }
                    } else {
                        // A normal return value: will lead to a commit.
                        throwableHolder.throwable = ex;
                        return null;
                    }
                } finally {
                    cleanupTransactionInfo(txInfo);
                }
            });
        } catch (ThrowableHolderException ex) {
            throw ex.getCause();
        } catch (TransactionSystemException ex2) {
            if (throwableHolder.throwable != null) {
                log.error("Application exception overridden by commit exception", throwableHolder.throwable);
                ex2.initApplicationException(throwableHolder.throwable);
            }
            throw ex2;
        } catch (Throwable ex2) {
            if (throwableHolder.throwable != null) {
                log.error("Application exception overridden by commit exception", throwableHolder.throwable);
            }
            throw ex2;
        }
        // Check result state: It might indicate a Throwable to rethrow.
        if (throwableHolder.throwable != null) {
            throw throwableHolder.throwable;
        }
        return result;
    }
}
Also used : StringUtils(cn.taketoday.util.StringUtils) Assert(cn.taketoday.lang.Assert) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) NoTransactionException(cn.taketoday.transaction.NoTransactionException) TransactionManager(cn.taketoday.transaction.TransactionManager) ClassUtils(cn.taketoday.util.ClassUtils) TransactionStatus(cn.taketoday.transaction.TransactionStatus) TransactionContextManager(cn.taketoday.transaction.reactive.TransactionContextManager) ConcurrentMap(java.util.concurrent.ConcurrentMap) Method(java.lang.reflect.Method) ReactiveTransaction(cn.taketoday.transaction.ReactiveTransaction) Properties(java.util.Properties) BeanFactoryAware(cn.taketoday.beans.factory.BeanFactoryAware) NamedThreadLocal(cn.taketoday.core.NamedThreadLocal) ConcurrentReferenceHashMap(cn.taketoday.util.ConcurrentReferenceHashMap) ReactiveAdapterRegistry(cn.taketoday.core.ReactiveAdapterRegistry) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) BeanFactory(cn.taketoday.beans.factory.BeanFactory) Mono(reactor.core.publisher.Mono) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) LoggerFactory(cn.taketoday.logging.LoggerFactory) Flux(reactor.core.publisher.Flux) BeanFactoryAnnotationUtils(cn.taketoday.beans.factory.annotation.BeanFactoryAnnotationUtils) ReactiveAdapter(cn.taketoday.core.ReactiveAdapter) Nullable(cn.taketoday.lang.Nullable) TransactionSystemException(cn.taketoday.transaction.TransactionSystemException) Logger(cn.taketoday.logging.Logger) InitializingBean(cn.taketoday.beans.factory.InitializingBean) TransactionSystemException(cn.taketoday.transaction.TransactionSystemException) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) CallbackPreferringPlatformTransactionManager(cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager) TransactionManager(cn.taketoday.transaction.TransactionManager) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) PlatformTransactionManager(cn.taketoday.transaction.PlatformTransactionManager) ReactiveTransactionManager(cn.taketoday.transaction.ReactiveTransactionManager) ReactiveAdapter(cn.taketoday.core.ReactiveAdapter) Nullable(cn.taketoday.lang.Nullable)

Aggregations

BeanFactory (cn.taketoday.beans.factory.BeanFactory)2 BeanFactoryAware (cn.taketoday.beans.factory.BeanFactoryAware)2 InitializingBean (cn.taketoday.beans.factory.InitializingBean)2 BeanFactoryAnnotationUtils (cn.taketoday.beans.factory.annotation.BeanFactoryAnnotationUtils)2 NamedThreadLocal (cn.taketoday.core.NamedThreadLocal)2 ReactiveAdapter (cn.taketoday.core.ReactiveAdapter)2 ReactiveAdapterRegistry (cn.taketoday.core.ReactiveAdapterRegistry)2 Assert (cn.taketoday.lang.Assert)2 Nullable (cn.taketoday.lang.Nullable)2 Logger (cn.taketoday.logging.Logger)2 LoggerFactory (cn.taketoday.logging.LoggerFactory)2 NoTransactionException (cn.taketoday.transaction.NoTransactionException)2 PlatformTransactionManager (cn.taketoday.transaction.PlatformTransactionManager)2 ReactiveTransaction (cn.taketoday.transaction.ReactiveTransaction)2 ReactiveTransactionManager (cn.taketoday.transaction.ReactiveTransactionManager)2 TransactionManager (cn.taketoday.transaction.TransactionManager)2 TransactionStatus (cn.taketoday.transaction.TransactionStatus)2 TransactionSystemException (cn.taketoday.transaction.TransactionSystemException)2 TransactionContextManager (cn.taketoday.transaction.reactive.TransactionContextManager)2 CallbackPreferringPlatformTransactionManager (cn.taketoday.transaction.support.CallbackPreferringPlatformTransactionManager)2