9

02.Spring事务的源码(一):入口及核心主流程

 4 years ago
source link: http://sunliangliang.com/?p=53
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

探寻Spring事务的入口类以及核心主流程

基础知识已经了解完毕,本篇主要讲解下Spring对于事务支持的源码。从入口类到主流程

我们通过一个简单的@Transactional的注解就完成了对于事务的支持。这里面的内部的构造大家也都知道是通过AOP的思想来实现的,那么到底是如何处理的,我们来一探究竟。

  • 事务的处理流程:Aop代理实现
  • 事务处理的入口类:TransactioanIntercepor
  • 事务的核心主流程:事务开启->执行业务流程 ?执行成功:提交事务,执行失败:回滚事务

1.AOP代理流程

Spring对于事务的管理,是用Aop来实现的。通过添加@Transational注解实现 事务的管理通过TransactionManager来处理

这里我们可以先通过一张图基于我们目前的知识对spring事务的基本流程有个印象。

  • TransactionInterceptorinvoke方法作为入口执行
    • 获取代理对象
    • 执行service的业务逻辑
    • 若出现异常则,回滚事务
    • 若执行成功,提交事务

2.Spring事务源码初探

2.1.入口类TransactioanIntercepor

TransactioanIntercepor会对我们添加了@Transactional注解的方法或者类进行拦截,之后就会在执行业务逻辑之前先调用该类。我们假设有一个流量充值的功能。代码片段如下:

  @Transactional
  public void finishRefillData(RefillRequest refillRequest) {
    // 完成支付转账
    accountAmountService.transfer(refillRequest.getUserAccountId(),
        refillRequest.getBusinessAccountId(), refillRequest.getPayAmount());
    // 创建充值订单
    refillOrderService.add(createRefillOrder(refillRequest));
  }

基于上面的代码片段,我们来研究下源码的执行流程。

2.2.执行流程

找到了入口类TransactioanIntercepor之后,我们可以找到如下代码

1.TransactioanIntercepor.invoke()

public Object invoke(final 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, new InvocationCallback() {
  @Override
  public Object proceedWithInvocation() throws Throwable {
   return invocation.proceed();
  }
 });
}

这里的targetClass即为我们注解@Transactional标注的类RefillDataCenterServiceImpl,核心的业务逻辑都在invokeWithinTransaction()方法中

2.TransactionAspectSupport.invokeWithinTransaction

通过类名xxxAspectxxx我们可以看出这是一个Aop的代理类。

下面这段逻辑是核心,包含了事务的开启,提交,回滚等。

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
  throws Throwable {

// If the transaction attribute is null, the method is non-transactional.
 final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
 //这里是JTATransactionManager
 final PlatformTransactionManager tm = determineTransactionManager(txAttr);
 //这里是RefillDataCenterServiceImpl的全限定名
 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.
   //这里执行我们具体的业务方法,即`RefillDataCenterService.finishRefillData()`
   retVal = invocation.proceedWithInvocation();
  }
  catch (Throwable ex) {
   // target invocation exception
   //如果上面的业务逻辑代码报错了,这里进行事务的回滚
   completeTransactionAfterThrowing(txInfo, ex);
   throw ex;
  }
  finally {
   cleanupTransactionInfo(txInfo);
  }
  //如果没有报错,这里进行事务的提交
  commitTransactionAfterReturning(txInfo);
  return retVal;
 }
  • 1.创建事务:
    • TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
  • 2.执行业务逻辑:
    • invocation.proceedWithInvocation()
  • 3.若执行业务失败:回滚事务
    • completeTransactionAfterThrowing(txInfo, ex)
  • 4.若业务执行成功:事务提交
    • commitTransactionAfterReturning(txInfo)

更多内容可关注公众号


Recommend

  • 134
    • www.linkedkeeper.com 7 years ago
    • Cache

    Spring源码解析之事务篇

    Spring源码解析之事务篇 原 Spring源码解析之事务篇 张强...

  • 47
    • 微信 mp.weixin.qq.com 5 years ago
    • Cache

    @Transactional Spring 事务源码分析

    @Transactional Spring事务源码分析 在Spring开发中,经常会用到这个注解,但它是怎么起到开启事务的作用的,还一知半解,只知道应该是基于AOP的,今天就来分析一波它的用法和具体实现。 编程式事务和声明式事务

  • 9

    时序数据库Influx-IOx源码学习十(查询主流程) - 刘涛华的个人空间 - OSCHINA - 中文开源技术交流社区 用代码...

  • 12

    简单概述 Webpack 整体运行流程实例化 Compiler entryOption 阶段,读取入口文件 Loader 编译对应文件,解析成 AST 找到对应依赖,递归编译处理,生成 ch...

  • 5
    • www.fly63.com 3 years ago
    • Cache

    零基础理解 PostCSS 的主流程

    本文适用于所有前端开发人员。文章会介绍 Postcss 的主功能实现原理,不是介绍 api...

  • 14

    本文转载自敖小剑的博客 经过前面基本概念和实现原理的介绍,大家对mixer check cache应该有了基本的了解,下面我...

  • 12

    经过前面基本概念和实现原理的介绍,大家对mixer check cache应该有了基本的了解,下面我们开始展开源代码来细细研读。 Check Cache的主要流程 Check Cache的调用入口 对mixer cache的调用在代码 proxy/src/istio/mixerclient/c...

  • 3
    • juejin.cn 2 years ago
    • Cache

    Mybatis源码主流程分析

    Mybatis源码主流程分析 2022年09月14日 11:02 ·  阅读 811 Mybatis 是一个 Data Ma...

  • 6

    C# WPF上位机开发(业务主流程才是核心)

  • 7

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         前面我们陆续学了qt的一些技术,这里面包括各个控件的使用,有定时器,有数据库,有图形的绘制等等。总体上说,截止到目前我们的确可以编写一些软件了。但仅仅是...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK