Spring的事务属于逻辑事务。不是物理事务。 Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JDBC或者JTA等持久化机制所提供的相关平台框架的事务来实现。例如JDBC的事物管理器就是DataSourceTransactionManager。 Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager:
1 2 3 4 5 public interface PlatformTransactionManager { TransactionStatus getTransaction (TransactionDefinition definition) throws TransactionException; void commit (TransactionStatus status) throws TransactionException; void rollback (TransactionStatus status) throws TransactionException; }
通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。所以Spring事务管理的一个优点就是为不同的事务API提供一致的编程模型。
Spring Boot 使用事务非常简单,需要@EnableTransactionManagement和@Transactional配合使用。首先使用注解@EnableTransactionManagement 开启事务支持后,然后在Service方法上添加注解@Transactional便可。@EnableTransactionManagement,启注解事务管理等同于xml配置方式的 <tx:annotation-driven />。
首先是EnableTransactionManagement类:
1 2 3 4 5 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {
这里会import TransactionManagementConfigurationSelector类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector <EnableTransactionManagement> { @Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String [] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String [] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME}; default : return null ; } } }
selectImports会返回两个类:AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration。
AutoProxyRegistrar的作用就是向BeanFactory注册InfrastructureAdvisorAutoProxyCreator.class。而InfrastructureAdvisorAutoProxyCreator继承自AbstractAdvisorAutoProxyCreator,就是让容器支持了AOP。
ProxyTransactionManagementConfiguration会加载关键的几个bean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @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()); 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; } }
BeanFactoryTransactionAttributeSourceAdvisor:实现了 PointcutAdvisor 接口,组合了TransactionAttributeSourcePointcut。
AnnotationTransactionAttributeSource:解析事务类,得到事务配置相关信息;
TransactionInterceptor:事务拦截器,实现了 Advice、MethodInterceptor 接口。TransactionInterceptor是个环绕增强,在目标方法执行前开启事务,执行完目标方法后,进行事务提交或者回滚;
事务代理类的创建
了解Spring AOP应该会熟悉这段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 public static boolean canApply (Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { return true ; } }
在前面 BeanFactoryTransactionAttributeSourceAdvisor 类,该类实现了 PointcutAdvisor 接口,其中的切面 pointcut 便是通过 TransactionAttributeSourcePointcut 来实现的。
1 2 3 4 5 6 7 8 9 public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { private TransactionAttributeSource transactionAttributeSource; private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut () { @Override protected TransactionAttributeSource getTransactionAttributeSource () { return transactionAttributeSource; } }; }
调用路径会到TransactionAttributeSourcePointcut的matches方法,该方法根据能否可以从目标 bean 中得到 TransactionAttribute 来判断是否匹配的。
1 2 3 4 5 6 7 public boolean matches (Method method, @Nullable Class<?> targetClass) { if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) { return false ; } TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null ); }
上面的tas即AnnotationTransactionAttributeSource。AnnotationTransactionAttributeSource父类AbstractFallbackTransactionAttributeSource实现了getTransactionAttribute方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public TransactionAttribute getTransactionAttribute (Method method, @Nullable Class<?> targetClass) { if (method.getDeclaringClass() == Object.class) { return null ; } Object cacheKey = getCacheKey(method, targetClass); Object cached = this .attributeCache.get(cacheKey); if (cached != null ) { if (cached == NULL_TRANSACTION_ATTRIBUTE) { return null ; } else { return (TransactionAttribute) cached; } } else { TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass); if (txAttr == null ) { this .attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE); } else { String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass); if (txAttr instanceof DefaultTransactionAttribute) { ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification); } if (logger.isDebugEnabled()) { logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr); } this .attributeCache.put(cacheKey, txAttr); } return txAttr; } }
再看看computeTransactionAttribute方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 protected TransactionAttribute computeTransactionAttribute (Method method, @Nullable Class<?> targetClass) { if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null ; } Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); TransactionAttribute txAttr = findTransactionAttribute(specificMethod); if (txAttr != null ) { return txAttr; } txAttr = findTransactionAttribute(specificMethod.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { return txAttr; } if (specificMethod != method) { txAttr = findTransactionAttribute(method); if (txAttr != null ) { return txAttr; } txAttr = findTransactionAttribute(method.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { return txAttr; } } return null ; }
从上面可知,方法级别上的注解会覆盖类级别上的注解,两个findTransactionAttribute方法都在AnnotationTransactionAttributeSource实现,
1 2 3 4 5 6 7 8 9 protected TransactionAttribute findTransactionAttribute (Method method) { return determineTransactionAttribute(method); } protected TransactionAttribute findTransactionAttribute (Class<?> clazz) { return determineTransactionAttribute(clazz); }
再看看determineTransactionAttribute方法:
1 2 3 4 5 6 7 8 9 protected TransactionAttribute determineTransactionAttribute (AnnotatedElement ae) { for (TransactionAnnotationParser annotationParser : this .annotationParsers) { TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae); if (attr != null ) { return attr; } } return null ; }
annotationParsers集合包含了3个类,分别是SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser。分别解析不同包的注解,这里的解析类是SpringTransactionAnnotationParser,其parseTransactionAnnotation方法:
1 2 3 4 5 6 7 8 9 10 public TransactionAttribute parseTransactionAnnotation (AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( ae, Transactional.class, false , false ); if (attributes != null ) { return parseTransactionAnnotation(attributes); } else { return null ; } }
以上代码讲解析目标元素上@Transactional注解的相关信息,然后封装成AnnotationAttributes类,其继承LinkedHashMap。
看看parseTransactionAnnotation方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 protected TransactionAttribute parseTransactionAnnotation (AnnotationAttributes attributes) { RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute (); Propagation propagation = attributes.getEnum("propagation" ); rbta.setPropagationBehavior(propagation.value()); Isolation isolation = attributes.getEnum("isolation" ); rbta.setIsolationLevel(isolation.value()); rbta.setTimeout(attributes.getNumber("timeout" ).intValue()); rbta.setReadOnly(attributes.getBoolean("readOnly" )); rbta.setQualifier(attributes.getString("value" )); ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList <RollbackRuleAttribute>(); Class<?>[] rbf = attributes.getClassArray("rollbackFor" ); for (Class<?> rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute (rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName" ); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute (rbRule); rollBackRules.add(rule); } Class<?>[] nrbf = attributes.getClassArray("noRollbackFor" ); for (Class<?> rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute (rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName" ); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute (rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; }
切面实现
TransactionInterceptor 实现了方法拦截器 MethodInterceptor 接口,用于对业务类进行事务增强。TransactionInterceptor 的 invoke 方法主要是调用了父类 TransactionAspectSupport 的 invokeWithinTransaction 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Override public Object invoke (final MethodInvocation invocation) throws Throwable { Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null ); return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback () { @Override public Object proceedWithInvocation () throws Throwable { return invocation.proceed(); } }); } protected Object invokeWithinTransaction (Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable { final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null ; try { retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } else { } }
invoke 方法里主要做以下几件事:
获取事务属性;
获取事务管理器;
创建事务;
执行目标方法;
遇到异常则回滚,正常结束则提交。
创建事务的是TransactionAspectSupport#createTransactionIfNecessary()方法,该方法的调用代码比较多,主要摘取比较重要的看一下:
1 2 3 4 5 6 7 ---+TransactionAspectSupport:createTransactionIfNecessary(); `---+AbstractPlatformTransactionManager:getTransaction(); +---AbstractPlatformTransactionManager:doGetTransaction(); `---+AbstractPlatformTransactionManager:doBegin(); +---DataSource:getConnection(); `---TransactionSynchronizationManager.bindResource();
参考:https://blog.csdn.net/wang704987562/article/details/88913808 https://blog.csdn.net/ai_xiangjuan/article/details/79687560 https://blog.csdn.net/u012562943/article/details/78333153 https://www.coder4.com/archives/5917 https://blog.csdn.net/dslztx/article/details/46636079