SpringCloudAlibaba整合分布式事务Seata

发布时间 2023-05-28 21:53:42作者: 上善若泪

1 整合分布式事务Seata

点击了解分布式事务Seata相关信息

1.1 环境搭建

1.1.1 Nacos搭建

点击了解Nacos原理和使用

1.1.2 Seata搭建

点击了解Seata搭建

1.2 项目搭建

1.2.1 项目示意

如下图中,alibaba-demo为外层父目录模块,call为调用模块,common为存放共同依赖实体模块,order为支持crud模块
在这里插入图片描述

1.2.2 pom.xml

1.2.2.1 alibaba-demo模块

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>alibaba-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>common</module>
        <module>order</module>
        <module>call</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.6.11</spring.boot.version>
        <spring.cloud.version>2021.0.4</spring.cloud.version>
        <spring.cloud.alibaba>2021.0.4.0</spring.cloud.alibaba>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

1.2.2.2 call模块

<?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>alibaba-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>call</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>


        <dependency>
            <groupId>org.example</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

</project>

1.2.2.3 order模块

该模块中引入 spring-cloud-starter-alibaba-seata 模块

<?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>alibaba-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>

    </dependencies>


</project>

1.2.2.4 common模块

<?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>alibaba-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.0</version>
        </dependency>
    </dependencies>

</project>

1.2.3 配置文件

1.2.3.1 order模块

server:
  port: 8000

spring:
  application:
    name: cloud-order-demo
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
    username: xxxx
    password: xxxx
    type: com.alibaba.druid.pool.DruidDataSource
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: xxxx
        password: xxxx


mybatis-plus:
  mapper-locations: 'classpath:mapper/*Mapper.xml'
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


seata:
  enabled: true
  tx-service-group: mygroup
  data-source-proxy-mode: AT
  service:
    vgroup-mapping:
      mygroup: default
    grouplist:
      default: 127.0.0.1:8091
  registry:
    nacos:
      application: my-stata-server
      group: SEATA_GROUP
      namespace: 5658186c-c382-453a-843e-6a490cc80480
      username: nacos
      password: nacos
      server-addr: 127.0.0.1:8848
  config:
    nacos:
      group: SEATA_GROUP
      namespace: 5658186c-c382-453a-843e-6a490cc80480
      username: nacos
      password: nacos
      server-addr: 127.0.0.1:8848
      data-id: seata.properties

注意:

  • 上面的 seata.tx-service-group: 自定义值 要和它自己 seata.service.vgroup-mapping.自定义值:default自定义值相对应
    还要和 服务端的seata.properties中的service.vgroupMapping.自定义值=default自定义值 相对应
  • 上面的seata.service.vgroup-mapping.自定义值:default要和服务端的seata.propertiesservice.default.grouplist=127.0.0.1:8091 中的 default 相对应
  • 如果启动有error报错:不能找到service.vgroupMapping.自定义值 的服务,可以把service.vgroupMapping.单独配置指定

1.2.3.2 call模块

server:
  port: 7000

spring:
  application:
    name: cloud-call
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos


logging:
  level:
    # feign日志以什么级别监控哪个接口
    cn.feign: debug

1.2.4 OpenFeign调用

在call模块中
调整feign日志级别

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

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

feign调用接口

import cn.entity.User;
import cn.feign.fallback.UserFeignFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@FeignClient(value = "cloud-order-demo",fallbackFactory = UserFeignFallbackFactory.class,path = "/user")
public interface UserFeignService {

    @PostMapping("/query")
    public List<User> queryAll();

    @PostMapping("/save")
    public boolean save(User user);
}

feign回调工厂接口,可以打印详细堆栈信息

import cn.entity.User;
import cn.feign.UserFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class UserFeignFallbackFactory implements FallbackFactory<UserFeignService> {
    @Override
    public UserFeignService create(Throwable cause) {
        log.error("异常原因:{}", cause.getMessage(), cause);
        return new UserFeignService(){
            @Override
            public List<User> queryAll() {
                return null;
            }

            @Override
            public boolean save(User user) {
                return false;
            }
        };
    }
}

1.2.5 order模块

controller

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    private IUserService userService;



    @PostMapping("/query")
    public List<User> query (){
        List<User> list = userService.list();
        return list;
    }

    @PostMapping("/save")
    @GlobalTransactional
    @GlobalLock
    public boolean save (@RequestBody User user){
        boolean save = userService.save(user);
        if(save){
            long count = userService.count();
            long i = count / 0;
        }
        return save;
    }

    @PostMapping("/add")
    public int add (@RequestBody User user){
        int i = userService.insertUser(user);
        return i;
    }


}

后续的server以及mapper模块都是集成mybatisplus,没有任何代码,因此不在赘述