默认情况下,Spring中的事务只对RuntimeExceprion方法回滚。

10.2 事务自定义标签

搜索annotation-driven 最终锁定TxNamespaceHandler
在遇到诸如<tx:annotation-driven> 开头的配置后,Spring都会使用AnnotationDrivenBeanDefinitionParser类的parse方法进行解析

  1. AnnotationDrivenBeanDefinitionParser
  2. public BeanDefinition parse(Element element, ParserContext parserContext) {
  3. registerTransactionalEventListenerFactory(parserContext);
  4. String mode = element.getAttribute("mode");
  5. if ("aspectj".equals(mode)) {
  6. // mode="aspectj"
  7. registerTransactionAspect(element, parserContext);
  8. if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
  9. registerJtaTransactionAspect(element, parserContext);
  10. }
  11. }
  12. else {
  13. // mode="proxy"
  14. AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
  15. }
  16. return null;
  17. }

10.2.1 注册InfrastructureAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator的类继承结构
image.png
spring中,所有bean的实例化时都会保证调用其postProcessAfterInitialization,其实现是父类AbstractAutoProxyCreator类中实现。

  1. AbstractAutoProxyCreator
  2. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  3. if (bean != null) {
  4. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  5. // 是否是由于避免循环依赖而创建的bean代理
  6. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  7. return wrapIfNecessary(bean, beanName, cacheKey);
  8. }
  9. }
  10. return bean;
  11. }
  12. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  13. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  14. return bean;
  15. }
  16. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  17. return bean;
  18. }
  19. //给定的bean类是否代表一个基础设施类,不应代理,或者配置了指定bean需要自动代理
  20. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  21. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  22. return bean;
  23. }
  24. // 创建代理
  25. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  26. if (specificInterceptors != DO_NOT_PROXY) {
  27. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  28. Object proxy = createProxy(
  29. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  30. this.proxyTypes.put(cacheKey, proxy.getClass());
  31. return proxy;
  32. }
  33. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  34. return bean;
  35. }

10.2.2 获取对应class/method的增强器

获取指定的bean对应的增强器,其中包含两个关键字:增强器与对应。也就是说getAdvicesAndAdvisorsForBean函数中,不但要找出增强器,而且还需要判断增强器是否满足要求。

  1. AbstractAutoProxyCreator
  2. protected Object[] getAdvicesAndAdvisorsForBean(
  3. Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
  4. List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
  5. if (advisors.isEmpty()) {
  6. return DO_NOT_PROXY;
  7. }
  8. return advisors.toArray();
  9. }
  10. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  11. // 寻找候选增强器
  12. List<Advisor> candidateAdvisors = findCandidateAdvisors();
  13. //候选增强器中寻找匹配项
  14. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  15. extendAdvisors(eligibleAdvisors);
  16. if (!eligibleAdvisors.isEmpty()) {
  17. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  18. }
  19. return eligibleAdvisors;
  20. }

1 寻找候选增强器

2 候选增强器中寻找匹配项

  1. public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  2. if (candidateAdvisors.isEmpty()) {
  3. return candidateAdvisors;
  4. }
  5. List<Advisor> eligibleAdvisors = new ArrayList<>();
  6. // 首先处理引介增强
  7. for (Advisor candidate : candidateAdvisors) {
  8. if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
  9. eligibleAdvisors.add(candidate);
  10. }
  11. }
  12. boolean hasIntroductions = !eligibleAdvisors.isEmpty();
  13. for (Advisor candidate : candidateAdvisors) {
  14. //引介增强 已经处理
  15. if (candidate instanceof IntroductionAdvisor) {
  16. // already processed
  17. continue;
  18. }
  19. //对于普通 bean 的处理
  20. if (canApply(candidate, clazz, hasIntroductions)) {
  21. eligibleAdvisors.add(candidate);
  22. }
  23. }
  24. return eligibleAdvisors;
  25. }

10.3 事务增强器

TransactionInterceptor 支撑着整个事务功能的架构。TransactionInterceptor 类继承自MethodInterceptor。所以其调用是从invoke开始的。

  1. protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
  2. final InvocationCallback invocation) throws Throwable {
  3. // If the transaction attribute is null, the method is non-transactional.
  4. TransactionAttributeSource tas = getTransactionAttributeSource();
  5. //提取对应事务属性
  6. final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
  7. //获取beanFactory 中的 TransactionManager
  8. final TransactionManager tm = determineTransactionManager(txAttr);
  9. if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
  10. ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
  11. if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
  12. throw new TransactionUsageException(
  13. "Unsupported annotated transaction on suspending function detected: " + method +
  14. ". Use TransactionalOperator.transactional extensions instead.");
  15. }
  16. ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
  17. if (adapter == null) {
  18. throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
  19. method.getReturnType());
  20. }
  21. return new ReactiveTransactionSupport(adapter);
  22. });
  23. return txSupport.invokeWithinTransaction(
  24. method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
  25. }
  26. PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
  27. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  28. //声明式事务
  29. if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
  30. //创建 TransactionInfo
  31. TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
  32. Object retVal;
  33. try {
  34. //执行被增强方法
  35. retVal = invocation.proceedWithInvocation();
  36. }
  37. catch (Throwable ex) {
  38. //异常回滚
  39. completeTransactionAfterThrowing(txInfo, ex);
  40. throw ex;
  41. }
  42. finally {
  43. //清除信息
  44. cleanupTransactionInfo(txInfo);
  45. }
  46. if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
  47. // Set rollback-only in case of Vavr failure matching our rollback rules...
  48. TransactionStatus status = txInfo.getTransactionStatus();
  49. if (status != null && txAttr != null) {
  50. retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
  51. }
  52. }
  53. //提交事务
  54. commitTransactionAfterReturning(txInfo);
  55. return retVal;
  56. }
  57. else {
  58. Object result;
  59. final ThrowableHolder throwableHolder = new ThrowableHolder();
  60. //编程式事务处理
  61. // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
  62. try {
  63. result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
  64. TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
  65. try {
  66. Object retVal = invocation.proceedWithInvocation();
  67. if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
  68. // Set rollback-only in case of Vavr failure matching our rollback rules...
  69. retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
  70. }
  71. return retVal;
  72. }
  73. catch (Throwable ex) {
  74. if (txAttr.rollbackOn(ex)) {
  75. // A RuntimeException: will lead to a rollback.
  76. if (ex instanceof RuntimeException) {
  77. throw (RuntimeException) ex;
  78. }
  79. else {
  80. throw new ThrowableHolderException(ex);
  81. }
  82. }
  83. else {
  84. // A normal return value: will lead to a commit.
  85. throwableHolder.throwable = ex;
  86. return null;
  87. }
  88. }
  89. finally {
  90. cleanupTransactionInfo(txInfo);
  91. }
  92. });
  93. }
  94. catch (ThrowableHolderException ex) {
  95. throw ex.getCause();
  96. }
  97. catch (TransactionSystemException ex2) {
  98. if (throwableHolder.throwable != null) {
  99. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  100. ex2.initApplicationException(throwableHolder.throwable);
  101. }
  102. throw ex2;
  103. }
  104. catch (Throwable ex2) {
  105. if (throwableHolder.throwable != null) {
  106. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  107. }
  108. throw ex2;
  109. }
  110. // Check result state: It might indicate a Throwable to rethrow.
  111. if (throwableHolder.throwable != null) {
  112. throw throwableHolder.throwable;
  113. }
  114. return result;
  115. }
  116. }

声明式事务主要有以下几个步骤。

  1. 获取事务的属性
  2. 加载配置中配置的TransactionManager
  3. 不同的事务处理方式使用不同的逻辑。对于声明事务的处理与编程式事务的处理,第一点区别在于事务属性上,因为编程式的事务处理不需要有事物属性的,第二点区别是TransactionManager上,CallBackPreferringPlatformTransactionManager实现PlatformTransactionManager接口。暴露出一个方法用于执行事务处理中心的回调。所以,这两种方式都可以用作事务处理的判断。
  4. 在目标方法执行前获取事物并收集事务信息。
  5. 执行目标方法
  6. 一旦出现异常,尝试异常处理
  7. 提交事务钱的事务信息清除。
  8. 提交事务。