【Seata】01 - Seata XA 模式 Demo 调用流程分析

news2024/9/23 23:34:40

文章目录

    • 前言
    • 参考目录
    • 版本说明
    • 前置知识
      • 1、关于事务的理论知识
      • 2、关于 Seata
      • 3、Seata 领域模型
    • 测试 Demo
      • 1、模块说明
      • 2、调用逻辑说明
      • 3、分析流程说明
      • 4、注意事项
    • Seata XA 模式 Commit 调用流程分析
      • 1、调用流程图
      • 2、XA 模式流程以及操作命令
      • 3、业务模块:流程入口
      • 3.1、全局事务注解 `@GlobalTransactional`
      • 3.2、开启全局事务
      • 4、分支事务
      • 4.1、XA Start
      • 4.1.1、分支事务注册
      • 4.1.2、XA start
      • 4.2、XA End & Prepare
      • 4.3、分支事务提交
      • 5、全局事务提交
    • Seata XA 模式 Rollback 调用流程分析
      • 1、调用流程图
      • 2、XA 模式流程以及操作命令
      • 3、事务回滚
      • 3.1、分支事务回滚
      • 3.2、 全局事务回滚
    • 附录
      • Commit 调用流程控制台输出
        • 业务模块(business-xa)
        • 库存模块(stock-xa)
        • 订单模块(order-xa)
        • 账户模块(account-xa)
        • 按时序整理的完整流程输出
      • Rollback 调用流程控制台输出
        • 业务模块(business-xa)
        • 库存模块(stock-xa)
        • 订单模块(order-xa)
        • 按时序整理的流程输出(省略部分报错信息)

前言

事务一直以来都是系统中基础而又重要的组成部分。事务的定义:

数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。(From:维基百科)

对于分布式系统而言,事务的控制变得更为重要,所以来学习一下分布式事务框架 Seata。

参考目录

  • Seata 官方文档
  • Seata 官方 Demo :seata-xa
  • Seata XA 模式
  • 《阿里云云原生架构实践》
    书本章节 3.5 介绍了分布式事务模式的相关内容。

版本说明

由于官方 Demo 版本较低,本文使用的版本如下:

  • SeataV1.7.0
  • druid-spring-boot-starterV1.2.16

前置知识

1、关于事务的理论知识

这一部分不详细展开,简单带过一下。

事务(Transaction)四大特性:ACID。

  • 原子性(Atomic)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

CAP 理论(布鲁尔定理):

对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性(Consistency) (等同于所有节点访问同一份最新的数据副本)
  • 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据)
  • 分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。)

根据定理,分布式系统只能满足三项中的两项而不可能满足全部三项。理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。

对于分布式系统来说,某种条件下 C 和 A 是相互矛盾的,因此只能保证 CP (强一致性)或 AP(最终一致性)。

2、关于 Seata

Seata(Simpe Extensible Autonomous Transcaction Architecture),简单可扩展自主事务架构。首先引用一下官方文档的说明:

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

关于各个模式后面的文章会一一展开介绍,本文主要介绍的是 XA 模式。

顺便一提,XA 模式实际上是一种协议,使用的模式是二阶段提交(2PC),遵循的是 CP 强一致性。

(截图自《阿里云云原生架构实践》)在这里插入图片描述

3、Seata 领域模型

关于领域模型,可以查看 官方文档 。

按照官方文档的图,我重新绘制了一张:

在这里插入图片描述

在 Seata 中,事务管理者 TM、资源管理者 RM、事务协调者 TC是三个重要概念,所有操作都围绕着这三者进行展开。

在代码调试之前,根据模型大致列举了一下关于这三者之间的关系:

在这里插入图片描述

这些接口包含了主要的操作方法,根据不同的事务模式有不同的实现类。

测试 Demo

1、模块说明

在这里插入图片描述

Demo 一共四个模块,是经典的下单流程。按照如下顺序启动

  • 账户模块(Port:8083)
  • 订单模块(Port:8082)
  • 库存模块(Port:8081)
  • 业务模块(Port:8084)

模块间使用 openfeign 进行调用。

2、调用逻辑说明

入口:业务模块

http://127.0.0.1:8084/purchase

业务逻辑:

  1. 调用业务模块接口(business-xa)
  2. 扣减商品库存(stock-xa)
  3. 新增账户订单(order-xa)
  4. 账户余额扣减(account-xa)

(截图自 GitHub README.md)在这里插入图片描述

3、分析流程说明

从领域模型可以知道,整个下单操作是一个全局事务,各个模块分属于各个分支事务。下面对源码进行分析时只对其中一个分支操作进行说明,其余分支操作都是相同的,就不再展开说明。

分析分为 Commit 和 Rollback 两种流程。

官方文档 对于 XA 模式有详细的说明,本文在此基础上进行展开。

4、注意事项

由于文章整理准备的时间比较长,调试的流程是反复进行的,因此在调试过程中也常常出现超时异常回滚,下面的流程分析当中,全局事务id(xid)等一些参数也许是不同的,所以特此提出以免出现误解。

为了完整体现整个全局事务流程,也在不断点的情况下对流程进行了截取分析并制作了流程图,详细的见下文。

Seata XA 模式 Commit 调用流程分析

1、调用流程图

在这里插入图片描述

步骤前面由数字标识,根据各模块控制台输出整理,详细见附录。

2、XA 模式流程以及操作命令

因为本文主要是 Seata XA 模式的说明,因此了解 XA 操作指令对于后文的调用流程也有帮助。以 Demo 中的业务流程为例进行说明:

-- 开启 XA 事务
xa start '192.168.2.126:8091:2252227458314035239';

-- SQL 执行 --
-- 库存扣减
update stock_tbl set count = count - 30 where commodity_code = 'C100000';
-- 订单新增
insert order_tbl(user_id,commodity_code,count,money) values('U100000','C100000',30,3000)
-- 余额扣减
update account_tbl set money = money - 3000 where user_id = 'U100000'
-- SQL 执行结束 --

-- XA 事务第一阶段: Prepare
xa prepare '192.168.2.126:8091:2252227458314035239';

-- XA 事务第二阶段: Commit
xa commit '192.168.2.126:8091:2252227458314035239';

3、业务模块:流程入口

io.seata.sample.controller.BusinessController
在这里插入图片描述

io.seata.sample.service.BusinessService#purchase
在这里插入图片描述

接口参数:
在这里插入图片描述

3.1、全局事务注解 @GlobalTransactional

io.seata.spring.annotation.GlobalTransactionalInterceptor#invoke
在这里插入图片描述

3.2、开启全局事务

io.seata.tm.api.TransactionalTemplate#execute
在这里插入图片描述

io.seata.tm.api.TransactionalTemplate#beginTransaction
在这里插入图片描述

io.seata.tm.api.DefaultGlobalTransaction#begin
在这里插入图片描述

io.seata.tm.DefaultTransactionManager#begin
在这里插入图片描述

使用 Netty 同步发送全局事务开启请求。

io.seata.tm.DefaultTransactionManager#syncCall
在这里插入图片描述

请求成功,返回全局事务id(xid)。

在这里插入图片描述

返回 io.seata.tm.api.DefaultGlobalTransaction#begin,绑定 xid。

RootContext.bind(xid);

io.seata.core.context.RootContext#bind
在这里插入图片描述

至此,全局事务开启完成。进入分支事务流程。

4、分支事务

以库存模块为例,分析库存扣减事务分支流程。

io.seata.sample.service.StockService#deduct
在这里插入图片描述

io.seata.rm.datasource.xa.PreparedStatementProxyXA#executeUpdate
在这里插入图片描述

io.seata.rm.datasource.xa.ExecuteTemplateXA#execute
在这里插入图片描述

这个方法包含了 XA 模式第一阶段的所有步骤(如下图):

在这里插入图片描述

下面分步骤进行说明。

4.1、XA Start

在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#setAutoCommit
在这里插入图片描述

4.1.1、分支事务注册

io.seata.rm.DefaultResourceManager#branchRegister
在这里插入图片描述

io.seata.rm.AbstractResourceManager#branchRegister
在这里插入图片描述

在这里插入图片描述

控制台输出:
在这里插入图片描述

4.1.2、XA start

在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#start
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#start
在这里插入图片描述

执行完毕,返回上级。

io.seata.rm.datasource.xa.ConnectionProxyXA#setAutoCommit
在这里插入图片描述

4.2、XA End & Prepare

在 XA start 逻辑执行完成之后,会执行 SQL 语句(略),然后到这一步骤。

io.seata.rm.datasource.xa.ExecuteTemplateXA#execute
在这里插入图片描述

在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#commit
在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#end
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#end
在这里插入图片描述

io.seata.rm.datasource.xa.ExecuteTemplateXA#execute
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#prepare
在这里插入图片描述

4.3、分支事务提交

io.seata.core.rpc.processor.client.RmBranchCommitProcessor#process
在这里插入图片描述

在这里插入图片描述

io.seata.rm.AbstractRMHandler#onRequest
在这里插入图片描述

io.seata.rm.AbstractRMHandler#handle
在这里插入图片描述

io.seata.core.exception.AbstractExceptionHandler#exceptionHandleTemplate
在这里插入图片描述

io.seata.rm.AbstractRMHandler#handle
在这里插入图片描述

io.seata.rm.AbstractRMHandler#doBranchCommit
在这里插入图片描述

io.seata.rm.datasource.xa.ResourceManagerXA#branchCommit
在这里插入图片描述

io.seata.rm.datasource.xa.ResourceManagerXA#finishBranch
在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#xaCommit
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#commit
在这里插入图片描述

5、全局事务提交

io.seata.tm.api.TransactionalTemplate#execute
在这里插入图片描述

io.seata.tm.api.TransactionalTemplate#commitTransaction
在这里插入图片描述

io.seata.tm.api.DefaultGlobalTransaction#commit
在这里插入图片描述

io.seata.tm.DefaultTransactionManager#commit
在这里插入图片描述

io.seata.tm.api.DefaultGlobalTransaction#commit
在这里插入图片描述

io.seata.tm.api.DefaultGlobalTransaction#suspend
在这里插入图片描述

io.seata.tm.api.TransactionalTemplate#commitTransaction
在这里插入图片描述

事务提交完成。控制台打印如下:

在这里插入图片描述

Seata XA 模式 Rollback 调用流程分析

1、调用流程图

在这里插入图片描述

步骤前面由数字标识,根据各模块控制台输出整理,详细见附录。

2、XA 模式流程以及操作命令

-- 开启 XA 事务
xa start '192.168.2.126:8091:2252227796909469729';

-- SQL 执行 --
-- 库存扣减
update stock_tbl set count = count - 30 where commodity_code = 'C100000';
-- 订单新增
insert order_tbl(user_id,commodity_code,count,money) values('U100000','C100000',30,3000)
-- 余额扣减 出现异常
update account_tbl set money = money - 3000 where user_id = 'U100000'
-- SQL 执行结束 --

-- XA 事务第一阶段: Prepare
xa prepare '192.168.2.126:8091:2252227796909469729';

-- XA 事务第二阶段: Rollback
xa rollback '192.168.2.126:8091:2252227796909469729';

由于全局事务开启步骤以及分支注册步骤相同,在此不再赘述。

3、事务回滚

注:在进行回滚操作断点调试时,很容易由于超时出现异常,并且会一直处于回滚重试状态(直到重试超时才会解除),该状态下 MySQL 表数据无法修改,也可能导致各模块无法正常启动运行。因此下面列举的回滚相关方法可能并没有断点操作。

当没有足够的余额时,抛出异常。

io.seata.sample.service.AccountService#reduce
在这里插入图片描述

io.seata.tm.api.TransactionalTemplate#execute
在这里插入图片描述

io.seata.tm.api.TransactionalTemplate#completeTransactionAfterThrowing
在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#rollback
在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#xaRollback
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#rollback
在这里插入图片描述

3.1、分支事务回滚

io.seata.core.rpc.processor.client.RmBranchRollbackProcessor#process
在这里插入图片描述

io.seata.rm.AbstractRMHandler#handle
在这里插入图片描述

io.seata.rm.AbstractRMHandler#doBranchRollback
在这里插入图片描述

io.seata.rm.DefaultResourceManager#branchRollback
在这里插入图片描述

io.seata.rm.datasource.xa.ResourceManagerXA#branchRollback
在这里插入图片描述

io.seata.rm.datasource.xa.ConnectionProxyXA#xaRollback
在这里插入图片描述

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection#rollback
在这里插入图片描述

3.2、 全局事务回滚

io.seata.tm.api.DefaultGlobalTransaction#rollback
在这里插入图片描述

io.seata.tm.DefaultTransactionManager#rollback
在这里插入图片描述

附录

Commit 调用流程控制台输出

业务模块(business-xa)

2023-08-24 11:30:27.497  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.2.126:8091:2252227458314035239]
2023-08-24 11:30:27.498  INFO 13604 --- [nio-8084-exec-6] io.seata.sample.service.BusinessService  : New Transaction Begins: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:33.591  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : transaction 192.168.2.126:8091:2252227458314035239 will be commit
2023-08-24 11:30:33.641  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : transaction end, xid = 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:33.641  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : [192.168.2.126:8091:2252227458314035239] commit status: Committed

库存模块(stock-xa)

2023-08-24 11:30:27.501  INFO 4312 --- [nio-8081-exec-3] io.seata.sample.service.StockService     : deduct stock balance in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:30.306  INFO 4312 --- [nio-8081-exec-3] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035240, lockKeys:null
2023-08-24 11:30:33.595  INFO 4312 --- [h_RMROLE_1_3_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035240, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.596  INFO 4312 --- [h_RMROLE_1_3_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035240 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.601  INFO 4312 --- [h_RMROLE_1_3_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035240 was committed.
2023-08-24 11:30:33.601  INFO 4312 --- [h_RMROLE_1_3_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

订单模块(order-xa)

2023-08-24 11:30:30.319  INFO 5272 --- [nio-8082-exec-4] io.seata.sample.service.OrderService     : create order in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:32.237  INFO 5272 --- [nio-8082-exec-4] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035241, lockKeys:null
2023-08-24 11:30:33.606  INFO 5272 --- [h_RMROLE_1_2_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035241, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.607  INFO 5272 --- [h_RMROLE_1_2_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035241 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.611  INFO 5272 --- [h_RMROLE_1_2_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035241 was committed.
2023-08-24 11:30:33.611  INFO 5272 --- [h_RMROLE_1_2_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

账户模块(account-xa)

2023-08-24 11:30:32.889  INFO 20808 --- [nio-8083-exec-3] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035242, lockKeys:null
2023-08-24 11:30:32.890  INFO 20808 --- [nio-8083-exec-3] io.seata.sample.service.AccountService   : reduce account balance in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:33.583  INFO 20808 --- [nio-8083-exec-3] io.seata.sample.service.AccountService   : balance after transaction: 7000
2023-08-24 11:30:33.629  INFO 20808 --- [h_RMROLE_1_4_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035242, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.631  INFO 20808 --- [h_RMROLE_1_4_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035242 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.635  INFO 20808 --- [h_RMROLE_1_4_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035242 was committed.
2023-08-24 11:30:33.635  INFO 20808 --- [h_RMROLE_1_4_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

按时序整理的完整流程输出

2023-08-24 11:30:27.497  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.2.126:8091:2252227458314035239]
2023-08-24 11:30:27.498  INFO 13604 --- [nio-8084-exec-6] io.seata.sample.service.BusinessService  : New Transaction Begins: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:27.501  INFO 4312 --- [nio-8081-exec-3] io.seata.sample.service.StockService     : deduct stock balance in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:30.306  INFO 4312 --- [nio-8081-exec-3] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035240, lockKeys:null
2023-08-24 11:30:30.319  INFO 5272 --- [nio-8082-exec-4] io.seata.sample.service.OrderService     : create order in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:32.237  INFO 5272 --- [nio-8082-exec-4] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035241, lockKeys:null
2023-08-24 11:30:32.889  INFO 20808 --- [nio-8083-exec-3] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227458314035239, branchId:2252227458314035242, lockKeys:null
2023-08-24 11:30:32.890  INFO 20808 --- [nio-8083-exec-3] io.seata.sample.service.AccountService   : reduce account balance in transaction: 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:33.583  INFO 20808 --- [nio-8083-exec-3] io.seata.sample.service.AccountService   : balance after transaction: 7000
2023-08-24 11:30:33.591  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : transaction 192.168.2.126:8091:2252227458314035239 will be commit
2023-08-24 11:30:33.595  INFO 4312 --- [h_RMROLE_1_3_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035240, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.596  INFO 4312 --- [h_RMROLE_1_3_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035240 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.601  INFO 4312 --- [h_RMROLE_1_3_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035240 was committed.
2023-08-24 11:30:33.601  INFO 4312 --- [h_RMROLE_1_3_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed
2023-08-24 11:30:33.606  INFO 5272 --- [h_RMROLE_1_2_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit 
process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035241, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.607  INFO 5272 --- [h_RMROLE_1_2_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035241 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.611  INFO 5272 --- [h_RMROLE_1_2_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035241 was committed.
2023-08-24 11:30:33.611  INFO 5272 --- [h_RMROLE_1_2_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed
2023-08-24 11:30:33.629  INFO 20808 --- [h_RMROLE_1_4_16] i.s.c.r.p.c.RmBranchCommitProcessor      : rm client handle branch commit process:BranchCommitRequest{xid='192.168.2.126:8091:2252227458314035239', branchId=2252227458314035242, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-24 11:30:33.631  INFO 20808 --- [h_RMROLE_1_4_16] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.2.126:8091:2252227458314035239 2252227458314035242 jdbc:mysql://127.0.0.1:3306/seata null
2023-08-24 11:30:33.635  INFO 20808 --- [h_RMROLE_1_4_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227458314035239-2252227458314035242 was committed.
2023-08-24 11:30:33.635  INFO 20808 --- [h_RMROLE_1_4_16] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed
2023-08-24 11:30:33.641  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : transaction end, xid = 192.168.2.126:8091:2252227458314035239
2023-08-24 11:30:33.641  INFO 13604 --- [nio-8084-exec-6] i.seata.tm.api.DefaultGlobalTransaction  : [192.168.2.126:8091:2252227458314035239] commit status: Committed

Rollback 调用流程控制台输出

业务模块(business-xa)

2023-08-25 08:56:42.530  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.2.126:8091:2252227796909469729]
2023-08-25 08:56:42.530  INFO 19324 --- [nio-8084-exec-7] io.seata.sample.service.BusinessService  : New Transaction Begins: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:44.405  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : transaction 192.168.2.126:8091:2252227796909469729 will be rollback
2023-08-25 08:56:44.428  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : transaction end, xid = 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:44.428  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : [192.168.2.126:8091:2252227796909469729] rollback status: Rollbacked

库存模块(stock-xa)

2023-08-25 08:56:42.532  INFO 19556 --- [nio-8081-exec-1] io.seata.sample.service.StockService     : deduct stock balance in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.534  INFO 19556 --- [nio-8081-exec-1] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469730, lockKeys:null
2023-08-25 08:56:44.417  INFO 19556 --- [_RMROLE_1_10_16] i.s.c.r.p.c.RmBranchRollbackProcessor    : rm handle branch rollback process:BranchRollbackRequest{xid='192.168.2.126:8091:2252227796909469729', branchId=2252227796909469730, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-25 08:56:44.418  INFO 19556 --- [_RMROLE_1_10_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacking: 192.168.2.126:8091:2252227796909469729 2252227796909469730 jdbc:mysql://127.0.0.1:3306/seata
2023-08-25 08:56:44.422  INFO 19556 --- [_RMROLE_1_10_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469730 was rollbacked
2023-08-25 08:56:44.422  INFO 19556 --- [_RMROLE_1_10_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacked result: PhaseTwo_Rollbacked

订单模块(order-xa)

2023-08-25 08:56:42.554  INFO 17280 --- [nio-8082-exec-9] io.seata.sample.service.OrderService     : create order in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.557  INFO 17280 --- [nio-8082-exec-9] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469731, lockKeys:null
java.lang.RuntimeException: Failed to call Account Service. 
	at io.seata.sample.service.OrderService.create(OrderService.java:37)
	at io.seata.sample.controller.OrderController.create(OrderController.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
2023-08-25 08:56:44.410  INFO 17280 --- [h_RMROLE_1_8_16] i.s.c.r.p.c.RmBranchRollbackProcessor    : rm handle branch rollback process:BranchRollbackRequest{xid='192.168.2.126:8091:2252227796909469729', branchId=2252227796909469731, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-25 08:56:44.411  INFO 17280 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacking: 192.168.2.126:8091:2252227796909469729 2252227796909469731 jdbc:mysql://127.0.0.1:3306/seata
2023-08-25 08:56:44.413  INFO 17280 --- [h_RMROLE_1_8_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469731 was rollbacked
2023-08-25 08:56:44.413  INFO 17280 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacked result: PhaseTwo_Rollbacked

账户模块(account-xa)

2023-08-25 08:56:42.566  INFO 7760 --- [nio-8083-exec-9] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469732, lockKeys:null
2023-08-25 08:56:42.567  INFO 7760 --- [nio-8083-exec-9] io.seata.sample.service.AccountService   : reduce account balance in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.570  INFO 7760 --- [nio-8083-exec-9] io.seata.sample.service.AccountService   : balance after transaction: -2000
2023-08-25 08:56:44.398  INFO 7760 --- [nio-8083-exec-9] i.s.rm.datasource.xa.ConnectionProxyXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469732 was rollbacked
java.lang.RuntimeException: Not Enough Money ...
	at io.seata.sample.service.AccountService.reduce(AccountService.java:31)
	at io.seata.sample.service.AccountService$$FastClassBySpringCGLIB$$533284cb.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
	at io.seata.sample.service.AccountService$$EnhancerBySpringCGLIB$$e159ca86.reduce(<generated>)
	at io.seata.sample.controller.AccountController.reduce(AccountController.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

按时序整理的流程输出(省略部分报错信息)

2023-08-25 08:56:42.530  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.2.126:8091:2252227796909469729]
2023-08-25 08:56:42.530  INFO 19324 --- [nio-8084-exec-7] io.seata.sample.service.BusinessService  : New Transaction Begins: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.532  INFO 19556 --- [nio-8081-exec-1] io.seata.sample.service.StockService     : deduct stock balance in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.534  INFO 19556 --- [nio-8081-exec-1] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469730, lockKeys:null
2023-08-25 08:56:42.554  INFO 17280 --- [nio-8082-exec-9] io.seata.sample.service.OrderService     : create order in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.557  INFO 17280 --- [nio-8082-exec-9] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469731, lockKeys:null
2023-08-25 08:56:42.566  INFO 7760 --- [nio-8083-exec-9] io.seata.rm.AbstractResourceManager      : branch register success, xid:192.168.2.126:8091:2252227796909469729, branchId:2252227796909469732, lockKeys:null
2023-08-25 08:56:42.567  INFO 7760 --- [nio-8083-exec-9] io.seata.sample.service.AccountService   : reduce account balance in transaction: 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:42.570  INFO 7760 --- [nio-8083-exec-9] io.seata.sample.service.AccountService   : balance after transaction: -2000
2023-08-25 08:56:44.398  INFO 7760 --- [nio-8083-exec-9] i.s.rm.datasource.xa.ConnectionProxyXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469732 was rollbacked
java.lang.RuntimeException: Not Enough Money ...
2023-08-25 08:56:44.405  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : transaction 192.168.2.126:8091:2252227796909469729 will be rollback
java.lang.RuntimeException: Failed to call Account Service. 
2023-08-25 08:56:44.410  INFO 17280 --- [h_RMROLE_1_8_16] i.s.c.r.p.c.RmBranchRollbackProcessor    : rm handle branch rollback process:BranchRollbackRequest{xid='192.168.2.126:8091:2252227796909469729', branchId=2252227796909469731, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-25 08:56:44.411  INFO 17280 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacking: 192.168.2.126:8091:2252227796909469729 2252227796909469731 jdbc:mysql://127.0.0.1:3306/seata
2023-08-25 08:56:44.413  INFO 17280 --- [h_RMROLE_1_8_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469731 was rollbacked
2023-08-25 08:56:44.413  INFO 17280 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacked result: PhaseTwo_Rollbacked
2023-08-25 08:56:44.417  INFO 19556 --- [_RMROLE_1_10_16] i.s.c.r.p.c.RmBranchRollbackProcessor    : rm handle branch rollback process:BranchRollbackRequest{xid='192.168.2.126:8091:2252227796909469729', branchId=2252227796909469730, branchType=XA, resourceId='jdbc:mysql://127.0.0.1:3306/seata', applicationData='null'}
2023-08-25 08:56:44.418  INFO 19556 --- [_RMROLE_1_10_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacking: 192.168.2.126:8091:2252227796909469729 2252227796909469730 jdbc:mysql://127.0.0.1:3306/seata
2023-08-25 08:56:44.422  INFO 19556 --- [_RMROLE_1_10_16] i.s.rm.datasource.xa.ResourceManagerXA   : 192.168.2.126:8091:2252227796909469729-2252227796909469730 was rollbacked
2023-08-25 08:56:44.422  INFO 19556 --- [_RMROLE_1_10_16] io.seata.rm.AbstractRMHandler            : Branch Rollbacked result: PhaseTwo_Rollbacked
2023-08-25 08:56:44.428  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : transaction end, xid = 192.168.2.126:8091:2252227796909469729
2023-08-25 08:56:44.428  INFO 19324 --- [nio-8084-exec-7] i.seata.tm.api.DefaultGlobalTransaction  : [192.168.2.126:8091:2252227796909469729] rollback status: Rollbacked

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握Six Sigma:逐步解锁业务流程优化的秘密之匙

一、Six Sigma方法简介 1. Six Sigma的起源和概念 Six Sigma起源于1980年代的摩托罗拉公司。当时的摩托罗拉在面临激烈的全球竞争和持续的质量问题时&#xff0c;发明了这种系统的管理方法&#xff0c;并通过实施&#xff0c;获得了显著的成绩。 所谓的“Six Sigma”&#x…

Tensorflow2.0搭建网络八股

目录 引言&#xff1a;keras与Tensorflow2.0结合 一、六步法 1.导入头文件&#xff1a;import 2.收集处理训练集和测试集&#xff1a;train, test&#xff1a; 3.描述各层网model tf.keras.models.Sequential&#xff1a; 4.描述使用什么优化反向传播&#xff1a;model.c…

Python中使用print()时如何实现不换行

平时刷题的时候大家可能会发现打印字符的时候需要你不换行才能得到正确答案&#xff0c;那么如何实现的。下面直接看例子。 使用print()函数时其实还有个默认的参数end&#xff0c;来看看具体怎么回事 list [a,b,c] for i in list:print(i)打印结果&#xff1a;在这里插入代…

【C/C++】父类指针指向子类对象 | 隐藏

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

CleanMyMac最新版4.14Mac清理软件下载安装使用教程

苹果电脑是很多人喜欢使用的一种电脑&#xff0c;它有着优美的外观&#xff0c;流畅的操作系统&#xff0c;丰富的应用程序和高效的性能。但是&#xff0c;随着时间的推移&#xff0c;苹果电脑也会产生一些不必要的文件和数据&#xff0c;这些文件和数据就是我们常说的垃圾。那…

docker服务如何正确关停

说明&#xff1a;停止 docker 服务之前&#xff0c;先把所有的容器都停掉&#xff0c;如果没停掉&#xff0c;再重启 docker 服务之后&#xff0c;所有的容器就会成为 Exited 状态。如果你只是想停止 docker 服务&#xff0c;docker 中的容器还继续提供服务&#xff0c;需要在d…

NVIDIA DLI 深度学习基础 答案 领取证书

最后一节作业是水果分类的任务&#xff0c;一共6类&#xff0c;使用之前学习的知识在代码段上进行填空。 加载ImageNet预训练的基础模型 from tensorflow import kerasbase_model keras.applications.VGG16(weights"imagenet",input_shape(224, 224, 3),include_t…

首页搜索框传递参数,并在搜索页面中的搜索框中进行显示,搜索框绑定回车键进行搜索

实现搜索条件和搜索内容固定&#xff0c;以及回车键搜索跳转 1.写出搜索条件和搜索框 <form class"parent"><select id"searchSelect" style"border: 1px solid #325da7;border-right: none;" value"resource"><opt…

Mysql B+数索引结构

一、B树和B树区别 二、 B 树形成过程 三、页分裂过程 3.1 页分裂过程实例 3.1.1 原有数据1、3、5形成如下数据页 3.1.2 先新插入数据4&#xff0c;因为 页10 最多只能放3条记录所以我们不得不再分配一个新页&#xff1a; 新分配的数据页编号可能并不是连续的&#xff0c;也…

threejs特殊几何体(一:文字几何体对象)

threejs中文字几何体通过newTextGeometry&#xff08;&#xff09;生成&#xff0c;它被单独作为一个类存在于threejs中const txtGeo new TextGeometry("threejs", { ...opts, font: font }); 我们先看效果&#xff1a; <template><div></div> &…

RJ45接口的PCB设计布局布线注意事项

网口模块的组成主要包括了&#xff1a;RJ45网口、变压器、PHY芯片及主芯片&#xff1b;还有一种RJ45与变压器进行了集成&#xff0c;分别如图1、图2所示&#xff1b; 图1 网口模块组成-RJ45与变压器未集成 图2 网口模块组成-RJ45与变压器集成 我们常见的网口有百兆网口和千兆网…

MySQL学习笔记(八)—— 锁

首先要说明&#xff0c;有的锁是我们自己想加的时候加的&#xff0c;比如全局锁要靠我们自己用命令去加。而有的锁是mysql默认就给你加上了&#xff0c;因为mysql要保证自己最起码的安全性。 InnoDB默认加的是行级锁。 一、全局锁 1.1 用途 全局锁就是把所有的表都给锁了&am…

【UniApp开发小程序】私聊功能后端实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

声明 本文提炼于个人练手项目&#xff0c;其中的实现逻辑不一定标准&#xff0c;实现思路没有参考权威的文档和教程&#xff0c;仅为个人思考得出&#xff0c;因此可能存在较多本人未考虑到的情况和漏洞&#xff0c;因此仅供参考&#xff0c;如果大家觉得有问题&#xff0c;恳…

Mac操作系统Safari 17全新升级:秋季推出全部特性

苹果的内置浏览器可能是Mac上最常用的应用程序&#xff08;是的&#xff0c;甚至比Finder、超级Mac Geeks还要多&#xff09;。因此&#xff0c;苹果总是为其浏览器Safari添加有用的新功能。在今年秋天与macOS Sonoma一起推出的第17版中&#xff0c;Safari可以帮助你提高工作效…

以getPositionList为例,查找接口函数定义及接口数据格式定义

job-app-master/pages/index/index.vue中299行 async getPositionList(type refresh, pulldown false) {this.status 请求中;if (type refresh) {this.query.page 1;} else {this.query.page;}let res await this.$apis.getPositionList(this.query);if (res) {if (type …

Oracle查锁表(史上最全)

Oracle查锁表 Oracle分两种锁&#xff0c;一种是DDL锁&#xff0c;一种是DML锁。一、Oracle DDL锁的解锁&#xff08;dba_ddl_locks视图&#xff09;1.1、查表的DDL锁的详情&#xff08;kill session脚本、表名、执行锁表的SQL等&#xff09;1.2、解锁表的DDL锁1.2.1、解锁表的…

202 | 抽象类、接口、内部类

抽象类 abstract 注意项 父类方法需要声明&#xff0c;但是有不确定性&#xff0c;考虑将该方法设计为抽象方法抽象方法没有实现的方法没有方法体&#xff08;跟接口的区别&#xff1f;&#xff09;抽象方法的类必须设置为抽象类&#xff0c;实现方法由其子类实现 abstract …

C语言指针入门详解

一、指针简介 指针(Pointer)是C语言的一个重要知识点&#xff0c;其使用灵活、功能强大&#xff0c;是C语言的灵魂指针与底层硬件联系紧密&#xff0c;使用指针可操作数据的地址&#xff0c;实现数据的间接访问指针就是地址&#xff0c;通过访问此地址来获取该地址存储的数据 …

AIGC人工智能涉及三十六职业,看看有没有你的职业(一)

文章目录 一只弹吉他的熊猫 神奇的企鹅 功夫熊猫 视觉光影下的女子 闪光灯效 局部柔光 生物光 LOGO设计 制作儿童绘本故事 换脸艺术 打造专属动漫头像 包装设计之美 建筑设计 如何转高清图 生成3D质感图标 生成微信表情包 探索美食摄影的奇妙之旅 蛋糕创意设…

docker-compose管理创建LNMP服务并运行Wordpress网站平台

文章目录 一&#xff0e;项目环境1. 环境描述2.项目需求 二&#xff0e;部署过程1.安装Docker2.安装Docker加速器3.Docker-Compose安装部署4.准备依赖文件、配置nginx5.配置mysql6.配置php7.编写docker-compose.yml8.验证 三.容器快照&#xff0c;然后将Docker镜像打包成tar包备…