后端微服务基础架构Spring Cloud

版本关系

版本发布说明-阿里云Spring Cloud Alibaba官网

选择

创建项目

创建父项目

什么都不动,创建即可

1) 删掉没用的文件

保留

2) pom中加入

复制代码
打包方式  <packaging>pom</packaging>

3) 删掉src

4) pom.xml中删除没用的

5)更改pom.xml中

复制代码
spring-boot-starter-parent版本为更改为3.3.4,点击右上角的maven标记刷新依赖

删掉依赖

properties更换为

复制代码
  <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>2023.0.3</spring-cloud.version>
        <spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
    </properties>

再加入:刷新

复制代码
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

完整的:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <packaging>pom</packaging>
    <groupId>com.i7i8i9</groupId>
    <artifactId>weifuwu3</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>weifuwu3</name>
    <description>weifuwu3</description>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>2023.0.3</spring-cloud.version>
        <spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建最外层服务

1.创建module ---services

就是个普通java module,不用选add sample code

pom中也是加入打包方式

<packaging>pom</packaging>

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>weifuwu3</artifactId>
        <groupId>com.i7i8i9</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>services</artifactId>
    <packaging>pom</packaging>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

删除src

创建微服务

新建module ,主要是确认一定在上面建立的services服务下,不用选add sample code,Parent一定要对,

创建完成后,在父级服务pom中可以看到<modules>

查看maven结构

可以点击齿轮,选中Group Modules

完善项目

导入公共依赖

主要是在最外层services pom.xml中加入,比如nacos

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>weifuwu3</artifactId>
        <groupId>com.i7i8i9</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>services</artifactId>
    <packaging>pom</packaging>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
<!--        导入nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>

在各层服务依赖中查看

启动

给每个微服务pom.xml导入Web依赖

在某个微服务上点击右键 generate,选择 edit starters

不行自己导

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>weifuwu3</artifactId>
        <groupId>com.i7i8i9</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-order</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

新建主程序

src/main/java下新建

com.i7i8i9.auth.AuthMainApplication

复制代码
package com.i7i8i9.order;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrderMainApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderMainApplication.class, args);
    }
}

编写application.yml

复制代码
spring.application.name=service-order
server.port=8080
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

Nacos

下载,启动

http://192.168.32.1:8848/nacos/index.html

基本原则

1.Gateway: 前后端之间会经过GateWay, 后端服务之间因为属于同一个工程,一般不经过

GateWay,但也可以经过

服务

1.目录

服务可以都放在服务模块下,但是需要在服务模块的pom.xml体现

pom.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>com.i7i8i9</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <packaging>pom</packaging>
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>service-product</module>
        <module>service-order</module>
        <module>seata-account</module>
        <module>seata-business</module>
        <module>seata-order</module>
        <module>seata-storage</module>
    </modules>

    <artifactId>services</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
   <dependencies>
<!--   sentinel是流量保护    -->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
       </dependency>
       <dependency>
             <!--        nucos 注册中心   服务发现-->
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       </dependency>
       <!--      所有下属微服务的配置来源-->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
       </dependency>
       <dependency>
           <!-- openfeign 远程调用-->
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-openfeign</artifactId>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <scope>annotationProcessor</scope>
       </dependency>
       <dependency>
           <groupId>com.i7i8i9</groupId>
           <artifactId>model</artifactId>
           <version>0.0.1-SNAPSHOT</version>
       </dependency>


   </dependencies>
</project>

Feign远程调用

指的是需要调用其他服务的服务

1.服务src下建立feign文件夹

2.服务主程序上加注释

复制代码
@EnableFeignClients(basePackages = "com.atguigu.business.feign")

3.Feign文件夹内建需要调用的抽象类客户端

主要目的是供serviceImp使用

快速的方式是去被调用controller方面里面复制

方法名前面可以去掉public

复制代码
package com.atguigu.business.feign;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;


@FeignClient(value="seata-storage")     //服务名称nacos里面有
public interface StorageFeignClient {

    //找到扣库存服务的接口复制其方法名和参数

    /**
     *
     * @param commodityCode
     * @param count
     * @return
     */
    @GetMapping("/deduct")
     String deduct(@RequestParam("commodityCode") String commodityCode,
                         @RequestParam("count") Integer count);
}

4.服务实现类

主要是装配Feign客户端,再调用其方法

复制代码
package com.atguigu.business.service.impl;

import com.atguigu.business.feign.OrderFeignClient;
import com.atguigu.business.feign.StorageFeignClient;
import com.atguigu.business.service.BusinessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class BusinessServiceImpl implements BusinessService {

    //第一步就是拿到远程服务客户端
    @Autowired
    StorageFeignClient storageFeignClient;

    @Autowired
    OrderFeignClient orderFeignClient;

    @Override
    public void purchase(String userId, String commodityCode, int orderCount) {
        //TODO 1. 扣减库存
        storageFeignClient.deduct(commodityCode,orderCount);
        //TODO 2. 创建订单
        orderFeignClient.create(userId,commodityCode,orderCount);
    }
}

GateWay

SpringCloud基础2------Nacos配置、Feign、Gateway-阿里云开发者社区

nacos(七): gateway(单体)-CSDN博客

创建服务

pom.xml引入gateway和loadbalence

复制代码
 <!--网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
        <!--消费者-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>3.1.5</version>
        </dependency>

新建module

加上服务发现@EnableDiscoveryClient

复制代码
package com.i7i8i9.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

启动

yml

application.yml

复制代码
spring:
  active: dev
  application:
     name: gateway
  cloud:
    nacos:
       discovery:
           server-addr: 127.0.0.1:8848
           username: nacos
           password: nacos
       config:
         server-addr: 127.0.0.1:8848
         file-extension: properties
         username: nacos
         password: nacos
       loadbalancer:
         nacos:
           enabled: true
    gateway:
       discovery:
         locator:
           enabled: true
       routes: # 网关路由配置
     #第一组网关路由配置,针对于服务service-auth
         - id: serviceAuth # 路由id,自定义,只要唯一即可
           uri: lb://service-auth # 指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
           predicates: # 路由断言。也就是判断请求是否符合路由规则的条件。predicates译为谓语、断言
              - Path=/auth/** # 路径断言。当请求路径满⾜Path指定的规则时,才进⾏路由换发
           filters:
              - StripPrefix=1    # 拼接好url之后去掉1层路径也就是p1
    #http://localhost:10010/auth/token,因为/auth/路径触发了第一个路由规则,路由去掉p1这一项,重新拼接为lb://service-auth/auth去获取访问的结果。:
  datasource:
    driver-class-name: ${i7i8i9.datasource.driver-class-name}
    url: jdbc:mysql://${i7i8i9.datasource.host}:${i7i8i9.datasource.port}/${i7i8i9.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
    username: ${i7i8i9.datasource.username}
    password: ${i7i8i9.datasource.password}
  • id: serviceAuth # 路由id,自定义,只要唯一即可

uri: lb://service-auth # 指的是从nacos中按照名称获取微服务,并遵循负载均衡策略

predicates: # 路由断言。也就是判断请求是否符合路由规则的条件。predicates译为谓语、断言

  • Path=/auth/** # 路径断言。当请求路径满⾜Path指定的规则时,才进⾏路由换发

filters:

  • StripPrefix=1 # 拼接好url之后去掉1层路径也就是p1

#http://localhost:10010/auth/token,因为/auth/路径触发了第一个路由规则,路由去掉p1这一项,重新拼接为lb://service-auth/auth去获取访问的结果。:

假设有个服务实际调用地址为

http://localhost:8085/token

则也可以用以下两种方式访问:

http://localhost:10010/service-auth/token 这种service-auth就是实际上nacos服务名称

http://localhost:10010/auth/token 这是标准的,auth就是上面的断言,就是当出现auth时就去调用nacos 里面的service-auth

404: 注意如果请求404则可能是最后面多了/

AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {...}, request: XMLHttpRequest, ...}

application-dev.yml

复制代码
server:
  port: 10010 #当前spring boot工程运行时所占用的端口号

i7i8i9:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: 120.79.150.231 #主机地址
    port: 3306 #端口号
    database: basic #当前需要连接的数据库
    username: admin #用户
    password: tyuueew333444IIIIOOO88qqq #密码

服务查看

跨域

可以使用nginx

nginx: download

默认80端口

D:\soft\nginx-1.27.5\conf

复制代码
4

nginx -s reload

npm run build

事务

每个微服务都有对应的数据库

本地事务

主要是单接口测试,自己操作自己的数据库

操作数据库的服务的main主类上

@EnableTransactionManagement

一般ServiceImpl类会加

@Transactional

注意没有引入mybatis是没有这个注解的

全局事务-alibaba seata

本地事务要先配好

1.启动客户端Seata-绿色软件

下载Seata Java Download | Apache Seata

要使用2.1.0

两次解压,找到文件夹seata-server

点击bat文件即可启动

登录 http://localhost:7091/,账号密码都是seata 7091是网页端口

注意服务监听端口不是7091,而是8091

2.为服务总配置引入seata

在最外层服务pom.xml中,ctrl进入

复制代码
spring-cloud-alibaba-dependencies

在里面搜索

可见seata的版本是2.1.0所以启动seata服务端一定要用2.1.0

复制下面的alibaba的seata,注意不是springboot的

复制代码
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        <version>2023.0.3.2</version>
      </dependency>

在服务最外层service模块下的pom.xml引入

不用写版本号

引入之后在maven依赖中可以看到已经有了

3.服务文件引入

可以配置每个服务的yml用于指定分组

但也可以不在yml配,默认为

复制代码
default_tx_group,因为如下有默认组

添加file.conf文件,以后也可以放到nacos里面

复制代码
service {
  #transaction service group mapping  default_tx_group是默认分组
  vgroupMapping.default_tx_group = "default"
  #only support when registry.type=file, please don't set multiple addresses
  #注意不是seara网页端口
  default.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}

4.标注全局事务

@GlobalTransactional

也就是需要配置TM,它是入口

复制代码
package com.atguigu.business.service.impl;

import com.atguigu.business.feign.OrderFeignClient;
import com.atguigu.business.feign.StorageFeignClient;
import com.atguigu.business.service.BusinessService;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class BusinessServiceImpl implements BusinessService {

    //第一步就是拿到远程服务客户端
    @Autowired
    StorageFeignClient storageFeignClient;

    @Autowired
    OrderFeignClient orderFeignClient;
@GlobalTransactional
    @Override
    public void purchase(String userId, String commodityCode, int orderCount) {
        //TODO 1. 扣减库存
        storageFeignClient.deduct(commodityCode,orderCount);
        //TODO 2. 创建订单
        orderFeignClient.create(userId,commodityCode,orderCount);
    }
}

四种事务模式

默认是AT模式,就是自动模式

XA模式:

使用早期数据库模式,第一阶段提交就没有真正提交, 一直占用数据库,阻塞等待

更改方法

TCC

全手动,适合于夹杂了非数据库事务,也就是广义的事务,比如发邮件,发短信

要额外写接口这三个阶段(准备,提交,回滚)要做什么

比如第一阶段已经发了短信,只能再第三阶段再发一个纠正短信了

Saga

长事务

可能要好多天,比如请假,要经过审批,就不适合于用锁了

基于消息队列,第二个人收到第一个人的消息再做事,某个人失败了就通知所有人失败了

其他人收到消息后使用自定义处理,也就是补偿代码

其它

1.配置输出为null

order.timeout=null;order.auto-confirm=nullorder.db-urlnull

原因

proerties:

复制代码
#spring.cloud.nacos.discovery.server-addr=localhost:8848

yml

没用discovery

复制代码
server:
  port:8900
spring:
  application:
    name: service-order
  cloud:
    nacos:
        server-addr: localhost:8848
        config:
          namespace: dev
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:db.properties?group=order

日志

给微服务配置远程日志

在每个服务的application.yml中给feign包

复制代码
logging:
  level:
    com.i7i8i9.feign: debug
复制代码
#注意:远程配置的优先级高于本地

server:
  port:8900    #虽然这里写了8090,但是实际使用端口还是可以在Edit configurattion中指定
spring:
  profiles:
    active: uat       #第1步: 指定本项目激活环境,该名字需要对应nacos的namespace
    include: feign      #包含yml标识 feign,也就是application-feign.yml
  application:
    name: service-order
  cloud:
    nacos:
        server-addr: localhost:8848
        config:
          namespace: ${spring.profiles.active:dev}   #获取激活环境名称,找到nacos同名命名空间,如果获取不到环境名称就使用冒号后面的默认值
#          :dev是默认值dev的意思,如果找不到这个变量
logging:
  level:
    com.i7i8i9.feign: debug





---
spring:               #on-profile: dev 也就是说dev需要启用的配置,每个环境要导入的不一定一样
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:db.properties?group=order
    activate:
      on-profile: dev


---
spring:               #on-profile: UAT 也就是说dev需要启用的配置,每个环境要导入的不一定一样
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:db.properties?group=order
    activate:
      on-profile: uat

---
spring:           #on-profile: prod 也就是说dev需要启用的配置,每个环境要导入的不一定一样
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:db.properties?group=order
    activate:
      on-profile: prod

然后在微服务的配置类里面把Level放到容器中(就是加上@Bean)

复制代码
package com.i7i8i9.config;

import feign.Logger;
import feign.RetryableException;
import feign.Retryer;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OrderConfig {

//    @Bean
   Retryer retryer(){
       return new Retryer.Default();
   }


    @Bean
    Logger.Level  feignLoggerLevel(){
        return  Logger.Level.FULL;
    }



    @LoadBalanced   //注解式负载均衡,不要难过其他操作
    @Bean
    RestTemplate restTemplate(){
        return new RestTemplate();
    }



}

注释

idea创建java类时自动配置注解 idea如何设置类的自动注释_mob64ca1415f0ab的技术博客_51CTO博客

前端

Vue3与ts中使用axios vue3加ts_mob64ca14031c97的技术博客_51CTO博客

Debug

1.seata两段事务debug

标注断点

全部服务都以debug模式启动

发送请求

刷新seata

可见因为标记了@GlobalTransactional出现一个全局事务

applicationId就是所属应用: seata-business

transactionName触发全局事务入口 purchase(java.lang.String, java.lang.String, int)

status:beigin

timeout: 1分钟没做完就过期

还可以点击最后面查看用到了哪些全局锁(每个服务修改自己数据前获得的,以保证别的服务不能穿插着改)

放行

报错

指向扣库存,原因是库存分支事务注册失败,超过了上述配置的60s导致

重新来

重新发送请求,再加个断点

放行

就会来到第二个断点

打开最右侧的包括分支事务

就可以查看分支事务,是已经注册完了的库存事务

全局锁也能看到信息

可以看到在数据表storage_tbl有一把全局锁

去storage_db数据库查看

数据此时是98

并且有undo日志

数据复制出来

复制代码
{"@class":"org.apache.seata.rm.datasource.undo.BranchUndoLog","xid":"192.168.32.1:8091:9628920695037968","branchId":9628920695037969,"sqlUndoLogs":["java.util.ArrayList",

[{"@class":"org.apache.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"storage_tbl","beforeImage":
{"@class":"org.apache.seata.rm.datasource.sql.struct.TableRecords","tableName":"storage_tbl","rows":["java.util.ArrayList",
[{"@class":"org.apache.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",
[{"@class":"org.apache.seata.rm.datasource.sql.struct.Field","name":"count","keyType":"NULL","type":4,"value":100},
{"@class":"org.apache.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":4,"value":1}]]}]]},"afterImage":
{"@class":"org.apache.seata.rm.datasource.sql.struct.TableRecords","tableName":"storage_tbl","rows":["java.util.ArrayList",
[{"@class":"org.apache.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",
[{"@class":"org.apache.seata.rm.datasource.sql.struct.Field","name":"count","keyType":"NULL","type":4,"value":98},
{"@class":"org.apache.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":4,"value":1}]]}]]}}]]}

有before镜像

有after镜像

目的就是为了恢复

保存订单处设置断点

因为订单设置了一定会失败,所以可以看到account和storage都undo_log

两个子事务

两个全局锁

相关推荐
Love__Tay2 小时前
笔记/云计算基础
笔记·学习·云计算
wuxuanok5 小时前
Web后端开发-分层解耦
java·笔记·后端·学习
wuxuanok6 小时前
Web后端开发-请求响应
java·开发语言·笔记·学习
蜡笔小电芯6 小时前
【C语言】指针与回调机制学习笔记
c语言·笔记·学习
im_AMBER7 小时前
学习日志03 python
学习
DKPT8 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
Green1Leaves9 小时前
pytorch学习-11卷积神经网络(高级篇)
pytorch·学习·cnn
DKPT16 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
好好研究18 小时前
学习栈和队列的插入和删除操作
数据结构·学习