Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别

        • 0. 相关术语:
        • 1. 整体流程:
          • 1.1. TM、RM注册
          • 1.2. 引入全局事务拦截器GlobalTransactionalInterceptor
          • 1.3. 请求时调用拦截器invoke方法,TM发起全局事务
          • 1.4. RM通过数据库代理执行本地事务:
            • 1.4 .1. 启用数据库自动代理:
            • 1.4 .2. 数据源代理执行SQL:
          • 1.5 TM发送commit/rollback给TC:
          • 1.7 分支事务提交/回滚:
        • 2. AT和XA的区别:

0. 相关术语:
  • TC一般指seata-server
  • TM一般就是事务操作接口入口的服务,也就是标注@GlobalTransactional的服务
  • RM一般就是涉及整体事务操作的服务
  • 比如确认订单加积分,订单服务就作为TM和RM,积分服务就作为RM

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第1张图片

实验代码可见GitHub

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第2张图片

1. 整体流程:

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第3张图片

  1. TM、RM注册
  2. 初始化后置处理器方法中引入全局事务拦截器GlobalTransactionalInterceptor
  3. 请求时调用拦截器invoke方法,TM发起全局事务
  4. RM通过数据库代理执行本地事务
  • 解析SQL - 关闭自动提交 - 查询前镜像 - 执行业务SQL - 查询后镜像 - 根据前后镜像构建undo_log - 提交写入undo_log - 手动提交业务SQL
  1. TM发送commit/rollback给TC
  2. 分支事务提交/回滚:
  • 如果提交:采用异步线程去删除undo_log,一阶段已经提交本地事务了
  • 如果回滚:根据分支事务id和全局事务xid获取undo_log(数据库表有唯一索引),然后进行反向补偿,删除undo_log
1.1. TM、RM注册
  • 自动配置类SeataAutoConfiguration引入GlobalTransactionScanner
  • GlobalTransactionScanner实现InitializingBean,在IOC创建bean时,会调用afterPropertiesSet方法
  • 内部调用initClient方法中,进行TM、RM注册

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第4张图片

1.2. 引入全局事务拦截器GlobalTransactionalInterceptor
  • GlobalTransactionScanner继承了AbstractAutoProxyCreator,是个后置处理器,并重写了wrapIfNecessary方法

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第5张图片

  • 在IOC创建bean时,会调用postProcessAfterInitialization后置处理器方法,然后执行wrapIfNecessary
  • 引入全局事务拦截器GlobalTransactionalInterceptor

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第6张图片

1.3. 请求时调用拦截器invoke方法,TM发起全局事务
  • 当发起请求,再调用Controller时会先调用拦截器,也就是全局事务拦截器GlobalTransactionalInterceptor的invoke()方法
  • 如果要发起全局事务就调用handleGlobalTransaction方法

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第7张图片

  • 调用transactionalTemplate.execute方法,进行事务创建/加入,发起全局事务

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第8张图片

beginTransaction是一个模板方法,tx.begin发起全局事务会生成和绑定全局事务xid

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第9张图片

1.4. RM通过数据库代理执行本地事务:
  • beginTransactionf发起全局事务后,business.execute()最终反射调用@GlobalTransactional注解的方法
  • 当业务方法中进行数据库操作时,seata通过数据库代理执行
  • 解析SQL - 关闭自动提交 - 查询前镜像 - 执行业务SQL - 查询后镜像 - 根据前后镜像构建undo_log - 提交写入undo_log - 手动提交业务SQL

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第10张图片

1.4 .1. 启用数据库自动代理:
  • 此处seata-all是1.4.2版本,需要在启动类加上@EnableAutoDataSourceProxy注解
  • 最终是会注册两个bean:SeataDataSourceBeanPostProcessor、SeataAutoDataSourceProxyCreator

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第11张图片

  • bean创建SeataDataSourceBeanPostProcessor时,调用后置处理器方法进行数据源代理(DataSourceProxy)

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第12张图片

  • 数据源获取Connection 的时候,也会对Connection 进行代理(ConnectionProxy):

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第13张图片

  • 通过ConnectionProxy获取statement时(父类AbstractConnectionProxy方法),seata也对statement进行了代理;

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第14张图片

1.4 .2. 数据源代理执行SQL:
  • seata对数据源到statement都进行了代理,当statement执行SQL时,最终调用ExecuteTemplate.execute核心方法

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第15张图片

调用链:

  • executor.execute → io.seata.rm.datasource.exec.BaseTransactionalExecutor#doExecute → executeAutoCommitTrue
  • executeAutoCommitFalse(args) → connectionProxy.commit(); → doCommit → processGlobalTransactionCommit

执行流程:

  • 解析 SQL:得到 SQL 的类型、表、条件等相关的信息
  • 关闭自动提交
  • 查询前镜像(原始数据):根据解析得到的条件信息,生成查询语句,定位数据。
  • 执行业务 SQL
  • 查询后镜像(修改后数据):根据前镜像的结果,通过 主键 定位数据。
  • 构建undo_log日志
  • 提交写入undo_log日志
  • 手动提交业务SQL,本地事务也提交了,但全局事务没有

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第16张图片
Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第17张图片

1.5 TM发送commit/rollback给TC:
  • RM执行完本地事务(也就是业务方法执行完),都执行正常TM就发送commit给TC,否则就rollback
  • 通过全局事务xid控制commit/rollback

Seata执行整体流程(AT模式)| Seata源码 - 自动配置、数据库代理 | AT和XA的区别_第18张图片

1.7 分支事务提交/回滚:
  • 如果提交:采用异步线程去删除undo_log,一阶段已经提交本地事务了
  • 如果回滚:根据分支事务id和全局事务xid获取undo_log(数据库表有唯一索引),然后进行反向补偿,删除undo_log
  • 详情可以见参考链接:seata客户端二阶段分支事务的提交和回滚
2. AT和XA的区别:

 核心区别在于:

  • AT模式一阶段本地事务提交完后会提交本地事务;
  • XA模式要在所有的本地事务执行完成后,TC才发送指令让所有的RM提交事务、释放本地锁。
  • 所以XA的性能会低,但能保证强一致性效果

你可能感兴趣的:(分布式事务,数据库,seata源码,seata数据库代理,seata的AT模式,seata)