聊聊spring tx的EnableTransactionManagement
序
本文主要研究一下spring tx的EnableTransactionManagement
EnableTransactionManagement
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/EnableTransactionManagement.java
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {/*** Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as* opposed to standard Java interface-based proxies ({@code false}). The default is* {@code false}. <strong>Applicable only if {@link #mode()} is set to* {@link AdviceMode#PROXY}</strong>.* <p>Note that setting this attribute to {@code true} will affect <em>all</em>* Spring-managed beans requiring proxying, not just those marked with* {@code @Transactional}. For example, other beans marked with Spring's* {@code @Async} annotation will be upgraded to subclass proxying at the same* time. This approach has no negative impact in practice unless one is explicitly* expecting one type of proxy vs another, e.g. in tests.*/boolean proxyTargetClass() default false;/*** Indicate how transactional advice should be applied.* <p><b>The default is {@link AdviceMode#PROXY}.</b>* Please note that proxy mode allows for interception of calls through the proxy* only. Local calls within the same class cannot get intercepted that way; an* {@link Transactional} annotation on such a method within a local call will be* ignored since Spring's interceptor does not even kick in for such a runtime* scenario. For a more advanced mode of interception, consider switching this to* {@link AdviceMode#ASPECTJ}.*/AdviceMode mode() default AdviceMode.PROXY;/*** Indicate the ordering of the execution of the transaction advisor* when multiple advices are applied at a specific joinpoint.* <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.*/int order() default Ordered.LOWEST_PRECEDENCE;} 復制代碼- EnableTransactionManagement有三個屬性,分別是proxyTargetClass、AdviceMode、order;它import了TransactionManagementConfigurationSelector
- proxyTargetClass設置為true表示使用基于子類實現的代理(CGLIB),設置為false表示使用基于接口實現的代理,默認為false
- AdviceMode表示是使用哪種transactional advice,有PROXY及ASPECTJ兩種,默認是AdviceMode.PROXY
TransactionManagementConfigurationSelector
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {/*** Returns {@link ProxyTransactionManagementConfiguration} or* {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}* and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},* respectively.*/@Overrideprotected String[] selectImports(AdviceMode adviceMode) {switch (adviceMode) {case PROXY:return new String[] {AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName()};case ASPECTJ:return new String[] {determineTransactionAspectClass()};default:return null;}}private String determineTransactionAspectClass() {return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);}} 復制代碼- TransactionManagementConfigurationSelector繼承了抽象類AdviceModeImportSelector,它覆蓋了selectImports,該方法根據adviceMode返回要創建的類名;如果是PROXY模式,則返回AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName();如果是ASPECTJ模式,則返回TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME或者是TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
AbstractTransactionManagementConfiguration
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/AbstractTransactionManagementConfiguration.java
@Configuration public abstract class AbstractTransactionManagementConfiguration implements ImportAware {@Nullableprotected AnnotationAttributes enableTx;/*** Default transaction manager, as configured through a {@link TransactionManagementConfigurer}.*/@Nullableprotected PlatformTransactionManager txManager;@Overridepublic void setImportMetadata(AnnotationMetadata importMetadata) {this.enableTx = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));if (this.enableTx == null) {throw new IllegalArgumentException("@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());}}@Autowired(required = false)void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {if (CollectionUtils.isEmpty(configurers)) {return;}if (configurers.size() > 1) {throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");}TransactionManagementConfigurer configurer = configurers.iterator().next();this.txManager = configurer.annotationDrivenTransactionManager();}@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public static TransactionalEventListenerFactory transactionalEventListenerFactory() {return new TransactionalEventListenerFactory();}} 復制代碼- AbstractTransactionManagementConfiguration為EnableTransactionManagement注解提供了通用的結構,這里主要是初始化了txManager,以及創建了TransactionalEventListenerFactory;它有三個子類,分別是ProxyTransactionManagementConfiguration、AspectJTransactionManagementConfiguration、AspectJJtaTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.java
@Configuration public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource());advisor.setAdvice(transactionInterceptor());if (this.enableTx != null) {advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionInterceptor transactionInterceptor() {TransactionInterceptor interceptor = new TransactionInterceptor();interceptor.setTransactionAttributeSource(transactionAttributeSource());if (this.txManager != null) {interceptor.setTransactionManager(this.txManager);}return interceptor;}} 復制代碼- ProxyTransactionManagementConfiguration繼承了AbstractTransactionManagementConfiguration,這里它注冊了BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource(AnnotationTransactionAttributeSource)、TransactionInterceptor
AnnotationTransactionAttributeSource
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSourceimplements Serializable {private static final boolean jta12Present;private static final boolean ejb3Present;static {ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader);ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader);}private final boolean publicMethodsOnly;private final Set<TransactionAnnotationParser> annotationParsers;/*** Create a default AnnotationTransactionAttributeSource, supporting* public methods that carry the {@code Transactional} annotation* or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.*/public AnnotationTransactionAttributeSource() {this(true);}/*** Create a custom AnnotationTransactionAttributeSource, supporting* public methods that carry the {@code Transactional} annotation* or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.* @param publicMethodsOnly whether to support public methods that carry* the {@code Transactional} annotation only (typically for use* with proxy-based AOP), or protected/private methods as well* (typically used with AspectJ class weaving)*/public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {this.publicMethodsOnly = publicMethodsOnly;if (jta12Present || ejb3Present) {this.annotationParsers = new LinkedHashSet<>(4);this.annotationParsers.add(new SpringTransactionAnnotationParser());if (jta12Present) {this.annotationParsers.add(new JtaTransactionAnnotationParser());}if (ejb3Present) {this.annotationParsers.add(new Ejb3TransactionAnnotationParser());}}else {this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());}}//......} 復制代碼- AnnotationTransactionAttributeSource的無參構造器,設置了publicMethodsOnly為true,同時創建了SpringTransactionAnnotationParser
TransactionInterceptor
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionInterceptor.java
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {/*** Create a new TransactionInterceptor.* <p>Transaction manager and transaction attributes still need to be set.* @see #setTransactionManager* @see #setTransactionAttributes(java.util.Properties)* @see #setTransactionAttributeSource(TransactionAttributeSource)*/public TransactionInterceptor() {}/*** Create a new TransactionInterceptor.* @param ptm the default transaction manager to perform the actual transaction management* @param attributes the transaction attributes in properties format* @see #setTransactionManager* @see #setTransactionAttributes(java.util.Properties)*/public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {setTransactionManager(ptm);setTransactionAttributes(attributes);}/*** Create a new TransactionInterceptor.* @param ptm the default transaction manager to perform the actual transaction management* @param tas the attribute source to be used to find transaction attributes* @see #setTransactionManager* @see #setTransactionAttributeSource(TransactionAttributeSource)*/public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {setTransactionManager(ptm);setTransactionAttributeSource(tas);}@Override@Nullablepublic Object invoke(MethodInvocation invocation) throws Throwable {// Work out the target class: may be {@code null}.// The TransactionAttributeSource should be passed the target class// as well as the method, which may be from an interface.Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// Adapt to TransactionAspectSupport's invokeWithinTransaction...return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);}//---------------------------------------------------------------------// Serialization support//---------------------------------------------------------------------private void writeObject(ObjectOutputStream oos) throws IOException {// Rely on default serialization, although this class itself doesn't carry state anyway...oos.defaultWriteObject();// Deserialize superclass fields.oos.writeObject(getTransactionManagerBeanName());oos.writeObject(getTransactionManager());oos.writeObject(getTransactionAttributeSource());oos.writeObject(getBeanFactory());}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {// Rely on default serialization, although this class itself doesn't carry state anyway...ois.defaultReadObject();// Serialize all relevant superclass fields.// Superclass can't implement Serializable because it also serves as base class// for AspectJ aspects (which are not allowed to implement Serializable)!setTransactionManagerBeanName((String) ois.readObject());setTransactionManager((PlatformTransactionManager) ois.readObject());setTransactionAttributeSource((TransactionAttributeSource) ois.readObject());setBeanFactory((BeanFactory) ois.readObject());}} 復制代碼- TransactionInterceptor繼承了抽象類TransactionAspectSupport,同時實現了MethodInterceptor, Serializable接口;其invoke方法首先讀取targetClass,然后調用了抽象類TransactionAspectSupport的invokeWithinTransaction方法
TransactionAspectSupport
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {// NOTE: This class must not implement Serializable because it serves as base// class for AspectJ aspects (which are not allowed to implement Serializable)!private static final Object DEFAULT_TRANSACTION_MANAGER_KEY = new Object();private static final ThreadLocal<TransactionInfo> transactionInfoHolder =new NamedThreadLocal<>("Current aspect-driven transaction");@Nullableprotected static TransactionInfo currentTransactionInfo() throws NoTransactionException {return transactionInfoHolder.get();}public static TransactionStatus currentTransactionStatus() throws NoTransactionException {TransactionInfo info = currentTransactionInfo();if (info == null || info.transactionStatus == null) {throw new NoTransactionException("No transaction aspect-managed TransactionStatus in scope");}return info.transactionStatus;}protected final Log logger = LogFactory.getLog(getClass());@Nullableprivate String transactionManagerBeanName;@Nullableprivate PlatformTransactionManager transactionManager;@Nullableprivate TransactionAttributeSource transactionAttributeSource;@Nullableprivate BeanFactory beanFactory;private final ConcurrentMap<Object, PlatformTransactionManager> transactionManagerCache =new ConcurrentReferenceHashMap<>(4);//...... /*** 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.* @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*/@Nullableprotected 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 PlatformTransactionManager tm = determineTransactionManager(txAttr);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {// Standard transaction demarcation with getTransaction and commit/rollback calls.TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;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 exceptioncompleteTransactionAfterThrowing(txInfo, ex);throw ex;}finally {cleanupTransactionInfo(txInfo);}commitTransactionAfterReturning(txInfo);return retVal;}else {final ThrowableHolder throwableHolder = new ThrowableHolder();// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.try {Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {TransactionInfo txInfo = prepareTransactionInfo(tm, 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);}});// Check result state: It might indicate a Throwable to rethrow.if (throwableHolder.throwable != null) {throw throwableHolder.throwable;}return result;}catch (ThrowableHolderException ex) {throw ex.getCause();}catch (TransactionSystemException ex2) {if (throwableHolder.throwable != null) {logger.error("Application exception overridden by commit exception", throwableHolder.throwable);ex2.initApplicationException(throwableHolder.throwable);}throw ex2;}catch (Throwable ex2) {if (throwableHolder.throwable != null) {logger.error("Application exception overridden by commit exception", throwableHolder.throwable);}throw ex2;}}}//...... } 復制代碼- TransactionAspectSupport的invokeWithinTransaction方法對于TransactionAttribute不為null且PlatformTransactionManager是CallbackPreferringPlatformTransactionManager類型的在TransactionCallback中事務處理;其他的則使用標準的getTransaction and commit/rollback calls模式來進行事務處理,執行前調用createTransactionIfNecessary,異常時調用completeTransactionAfterThrowing,finally時調用cleanupTransactionInfo,最后調用commitTransactionAfterReturning
createTransactionIfNecessary
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/*** Create a transaction if necessary based on the given TransactionAttribute.* <p>Allows callers to perform custom TransactionAttribute lookups through* the TransactionAttributeSource.* @param txAttr the TransactionAttribute (may be {@code null})* @param joinpointIdentification the fully qualified method name* (used for monitoring and logging purposes)* @return a TransactionInfo object, whether or not a transaction was created.* The {@code hasTransaction()} method on TransactionInfo can be used to* tell if there was a transaction created.* @see #getTransactionAttributeSource()*/@SuppressWarnings("serial")protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {// If no name specified, apply method identification as transaction name.if (txAttr != null && txAttr.getName() == null) {txAttr = new DelegatingTransactionAttribute(txAttr) {@Overridepublic String getName() {return joinpointIdentification;}};}TransactionStatus status = null;if (txAttr != null) {if (tm != null) {status = tm.getTransaction(txAttr);}else {if (logger.isDebugEnabled()) {logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +"] because no transaction manager has been configured");}}}return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);}/*** Prepare a TransactionInfo for the given attribute and status object.* @param txAttr the TransactionAttribute (may be {@code null})* @param joinpointIdentification the fully qualified method name* (used for monitoring and logging purposes)* @param status the TransactionStatus for the current transaction* @return the prepared TransactionInfo object*/protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,@Nullable TransactionAttribute txAttr, String joinpointIdentification,@Nullable TransactionStatus status) {TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);if (txAttr != null) {// We need a transaction for this method...if (logger.isTraceEnabled()) {logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");}// The transaction manager will flag an error if an incompatible tx already exists.txInfo.newTransactionStatus(status);}else {// The TransactionInfo.hasTransaction() method will return false. We created it only// to preserve the integrity of the ThreadLocal stack maintained in this class.if (logger.isTraceEnabled()) {logger.trace("Don't need to create transaction for [" + joinpointIdentification +"]: This method isn't transactional.");}}// We always bind the TransactionInfo to the thread, even if we didn't create// a new transaction here. This guarantees that the TransactionInfo stack// will be managed correctly even if no transaction was created by this aspect.txInfo.bindToThread();return txInfo;} 復制代碼- createTransactionIfNecessary方法基于TransactionAttribute判斷是否需要新創建transaction,然后執行prepareTransactionInfo創建TransactionInfo并bindToThread
completeTransactionAfterThrowing
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/*** Handle a throwable, completing the transaction.* We may commit or roll back, depending on the configuration.* @param txInfo information about the current transaction* @param ex throwable encountered*/protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {if (txInfo != null && txInfo.getTransactionStatus() != null) {if (logger.isTraceEnabled()) {logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +"] after exception: " + ex);}if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {try {txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());}catch (TransactionSystemException ex2) {logger.error("Application exception overridden by rollback exception", ex);ex2.initApplicationException(ex);throw ex2;}catch (RuntimeException | Error ex2) {logger.error("Application exception overridden by rollback exception", ex);throw ex2;}}else {// We don't roll back on this exception.// Will still roll back if TransactionStatus.isRollbackOnly() is true.try {txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());}catch (TransactionSystemException ex2) {logger.error("Application exception overridden by commit exception", ex);ex2.initApplicationException(ex);throw ex2;}catch (RuntimeException | Error ex2) {logger.error("Application exception overridden by commit exception", ex);throw ex2;}}}} 復制代碼- completeTransactionAfterThrowing用于處理異常情況,它根據TransactionInfo及Throwable信息判斷是要rollback還是commit
cleanupTransactionInfo
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/*** Reset the TransactionInfo ThreadLocal.* <p>Call this in all cases: exception or normal return!* @param txInfo information about the current transaction (may be {@code null})*/protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {if (txInfo != null) {txInfo.restoreThreadLocalStatus();}} 復制代碼- cleanupTransactionInfo用于重置ThreadLocal的TransactionInfo
commitTransactionAfterReturning
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/*** Execute after successful completion of call, but not after an exception was handled.* Do nothing if we didn't create a transaction.* @param txInfo information about the current transaction*/protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {if (txInfo != null && txInfo.getTransactionStatus() != null) {if (logger.isTraceEnabled()) {logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");}txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());}} 復制代碼- commitTransactionAfterReturning用于在方法執行成功時來commit事務
小結
- EnableTransactionManagement有三個屬性,分別是proxyTargetClass、AdviceMode、order;它import了TransactionManagementConfigurationSelector;proxyTargetClass設置為true表示使用基于子類實現的代理(CGLIB),設置為false表示使用基于接口實現的代理,默認為false;AdviceMode表示是使用哪種transactional advice,有PROXY及ASPECTJ兩種,默認是AdviceMode.PROXY
- TransactionManagementConfigurationSelector繼承了抽象類AdviceModeImportSelector,它覆蓋了selectImports,該方法根據adviceMode返回要創建的類名;如果是PROXY模式,則返回AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName();如果是ASPECTJ模式,則返回TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME或者是TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
- ProxyTransactionManagementConfiguration繼承了AbstractTransactionManagementConfiguration,這里它注冊了BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource(AnnotationTransactionAttributeSource)、TransactionInterceptor
- TransactionInterceptor繼承了抽象類TransactionAspectSupport,同時實現了MethodInterceptor, Serializable接口;其invoke方法首先讀取targetClass,然后調用了抽象類TransactionAspectSupport的invokeWithinTransaction方法
- TransactionAspectSupport的invokeWithinTransaction方法對于TransactionAttribute不為null且PlatformTransactionManager是CallbackPreferringPlatformTransactionManager類型的在TransactionCallback中事務處理;其他的則使用標準的getTransaction and commit/rollback calls模式來進行事務處理,執行前調用createTransactionIfNecessary,異常時調用completeTransactionAfterThrowing,finally時調用cleanupTransactionInfo,最后調用commitTransactionAfterReturning
doc
- 5.7. Transactionality
- Transactions with Spring and JPA
- Using Transactions in Spring Data JPA
轉載于:https://juejin.im/post/5cb53f5af265da03b4460748
總結
以上是生活随笔為你收集整理的聊聊spring tx的EnableTransactionManagement的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录Nginx模块开发
- 下一篇: UIModalPresentationS