spring cloud alibaba 整合seata1.4(下)

上一篇文章讲了如何安装seata后太晚了。参考链接https://blog.csdn.net/xt_yangjie/article/details/112549404

接下来研究下如何使用seata1.4 整合spring cloud alibaba 2.2.3.RELEASE 以及spring boot 2.3

注:

该篇文章整合了nacos 必须要先安装nacos。nacos安装还是比较简单的比seata简单很多,自行查阅资料安装。

配置文件里面的配置需要 改成自己对应的链接、nacos组、命名空间 以及订阅的服务  idea还需要安装lombok插件

整合了spring boot+nacos+dubbo+seata

源码地址  https://gitee.com/xt_yangjie/spring-cloud-alibaba-demo

 

开整 。。。。。。。。。

先搭建服务架构

 

- spring-cloud-parent 父工程 主要做子项目jar包的版本管理 和所有子项目都需要引入的jar包

   -spring-cloud-common 所有包需要的公共功能 比如工具类

   -spring-cloud-module 存放各个模块 比如 支付 订单 库存等模块

         -pay-service 支付服务的具体实现

         -pay-service-api 支付服务对外暴露的接口以及vo实体 其他服务需要引用该服务需要maven依赖该包就行

         -user-service 用户服务

         -user-service-api 用户服务暴露的接口

   -spring-cloud-service 服务端 比如网关 限流 熔断等

      -alibaba-gateway-server 网关服务

 

 

spring-cloud-parent pom.xml 主要做子项目jar包的版本管理 和所有子项目都需要引入的jar包

<?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>com.jsg</groupId>
    <artifactId>jsg-cloud-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>spring-cloud-service</module>
        <module>spring-cloud-module</module>
        <module>spring-cloud-common</module>
    </modules>

    <name>jsg-cloud-parent</name>
    <packaging>pom</packaging>
    <description>spring cloud alibaba父工程</description>


    <!-- 使用jdk1.8 -->
    <properties>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <spring.boot.version>2.2.8.RELEASE</spring.boot.version>
        <spring.cloud.alibaba.version>2.2.3.RELEASE</spring.cloud.alibaba.version>
        <mybatisplus.springboot.version>2.3</mybatisplus.springboot.version>
        <druid.spring.boot.starter>1.2.4</druid.spring.boot.starter>
    </properties>



    <!-- 统一 spring cloud alibaba 以及springboot版本依赖管理
     spring cloud alibaba  1.5.x 版本适用于 Spring Boot 1.5.x
     spring cloud alibaba  2.0.x 版本适用于 Spring Boot 2.0.x
     spring cloud alibaba  2.1.x 版本适用于 Spring Boot 2.1.x
     spring cloud alibaba  2.2.x 版本适用于 Spring Boot 2.2.x
     -->
    <dependencyManagement>
        <dependencies>
            <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- mybatis plus 整合springboot 版本管理-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatisplus.springboot.version}</version>
            </dependency>

            <!-- 啊里的 druid 数据源版本管理-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.spring.boot.starter}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 所有子工程都有lombok -->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


    </dependencies>

</project>

 

 

-------------------------------------------------------支付服务-------------------------------------------------------

pay-service-api  新增一个对外暴露的服务接口 和VO实体

package com.jsg.pay.entity;

import lombok.Getter;
import lombok.Setter;

/**
 * @Author: YangJie
 * @Date: 2021/1/15 2:56 下午
 */
@Getter
@Setter
public class DemoPayVo {

    private Double money;
}
package com.jsg.pay.dubbo;

import com.jsg.pay.entity.DemoPayVo;

/**
 * @Author: YangJie
 * @Date: 2021/1/15 3:05 下午
 */
public interface DemoPayDubboService {
    
    //新增一笔付款金额
    int saveMoney(DemoPayVo demoPayVo);
    
}

结构入下图

 

 

接下来用pay-service具体实现该接口 结构图

 

 

pay-service  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>spring-cloud-module</artifactId>
        <groupId>com.jsg</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>pay-service</artifactId>


    <dependencies>

        <!-- 导入支付模块对外暴露的dubbo接口和实体-->
        <dependency>
            <groupId>com.jsg</groupId>
            <artifactId>pay-service-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- 数据库相关 开始-->
        <!-- mysql 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- mybatis plus 整合-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!-- 整合阿里的druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <!-- 数据库相关 结束-->


        <!-- web 应用(能够已jar或者war放tomca他的形式启动) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!-- spring cloud alibaba 整合nacos配置中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!-- spring cloud alibaba  整合nacos 服务注册/管理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- spring cloud alibaba 整合dubbo   -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

        <!-- 整合spring alibaba cloud的seata 开始
        需要排除 seata-spring-boot-starter 在引入 因为客户端版本可能不一致 我们使用的是1.4的服务端版本-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- 整合spring alibaba cloud的seata 结束 -->

        <!--  junit 测试所需的jar包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


    </dependencies>

</project>

 

bootstrap.yml 会优于application.yml 先加载 nacos的配置必须放到bootstrap.yml

bootstrap.yml

#抽取出nacos公共的配置 方便修改 启动配置中只配置nacos的 其他在application.yml中
nacos:
  service-address: 127.0.0.1:8848 #naocs地址需要带端口80也需要
  namespace: dev #nacos命名空间 比如dev 开发环境
  group: DEV_GROUP #nacos分组 比如 XXX业务组
  username: nacos
  password: nacos
  dubbo:
    namespace: dubbo #dubbo服务注册到nacos的命名空间
    group: DUBBO_GROUP #dubbo服务注册到nacos的组名
  seata:
    server: seata-server #这里必须和seata注册到nacos的服务名一样
    group: SEATA_GROUP #seata服务注册到nacos的组名SEATA_GROUP

#配置注册中心
spring:
  application:
    name: pay-application #应用名字
  main:
    allow-bean-definition-overriding: true # 解决Bean重复定义问题
  cloud:
    nacos:
      discovery:
        server-addr: ${nacos.service-address} #nacos服务注册地址
        namespace: ${nacos.namespace} #nacos服务注册的命名空间
        group: ${nacos.group} #nacos服务注册的group
      config:
        server-addr: ${nacos.service-address} #nacos配置中心地址
        namespace: ${nacos.namespace} #nacos配置中心的命名空间
        group: ${nacos.group} #acos配置中心的group
        file-extension: yml #程序读取的主配置文件 拼接起来为payService.yml(spring.application.name+file-extension)
        extension-configs[0]: #第一个扩展配置(pay-application.yml有配置相同项将覆盖下面配置的 )
          data-id: common.yml #配置文件名字
          group: ${nacos.group} #配置文件所属分组
          refresh: true #是否动态刷新

application.yml

server:
  port: 8081
#数据源配置 使用啊里的druid
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/jsg_dev?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
      username: root
      password: root


#dubbo配置也可以写在nacos中  如果有不同的这可以覆盖
dubbo:
  cloud:
    subscribed-services: pay-application #订阅的服务 多个以,隔开 默认*不建议会有警告
  scan:
    base-packages: com.jsg.pay.dubbo.impl #注明dubbo扫描的包(有点像spring扫描包的配置该包下面的所有标注@DubboService的类都会扫描)
  application:
    #name: ${spring.application.name} #注入nacos的服务名
    # 禁用QOS同一台机器可能会有端口冲突现象
    qos-enable: false
    qos-accept-foreign-ip: false
  registry:
    address: nacos://${nacos.service-address} #dubbo服务注入nacos注册中心地址
    group: ${nacos.dubbo.group} #指定dubbo服务的组名
    parameters[namespace]: ${nacos.dubbo.namespace} #指定dubbo服务的命名空间
  protocol:
    port: -1 #自动生成端口号(从20880自增)
    name: dubbo
  consumer:
    check: false #启动检查服务是否存在(默认true),建议关闭,不然服务不存在启动有可能报错
    timeout: 4000 #设置超时时间 ms

#seata配置 更多配置参考 https://github.com/seata/seata/blob/1.4.0/script/client/spring/application.yml
seata:
  enabled: true #开启seata支持
  tx-service-group: my_test_tx_group #这里需要和config.txt 文件中的service.vgroupMapping.my_test_tx_group=default一致
  enable-auto-data-source-proxy: true
  #seata整合nacos配置中心
  config:
    type: nacos
    nacos:
      group: ${nacos.seata.group} #seata服务注册到nacos的组名SEATA_GROUP
      server-addr: ${nacos.service-address}
      username: ${nacos.username}
      password: ${nacos.password}
  #seata整合nacos注册中心
  registry:
    type: nacos
    nacos:
      server-addr: ${nacos.service-address}
      username: ${nacos.username}
      password: ${nacos.password}
      application: ${nacos.seata.server} #这里必须和seata注册到nacos的服务名一样默认seata-server
      group: ${nacos.seata.group} #seata服务注册到nacos的组名SEATA_GROUP


#mybatis plus 配置
mybatis-plus:
  configuration:
    call-setters-on-nulls: true
    map-underscore-to-camel-case: true
    cache-enabled: false
  #    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-column-underline: true  #驼峰下划线转换
    capital-mode: true    #数据库大写下划线转换
    refresh-mapper: true  #刷新mapper 调试神器
    db-config:
      update-strategy: not_null #设置更新规则 null不更新
  mapper-locations: classpath*:/mapper/*Mapper.xml,classpath*:/mapper/*/*Mapper.xml #设置扫描mapper.xml的路径

 

新增一个mapper 插入数据库

DemoMapper.java

package com.jsg.pay.mybatisplus.mapper;

import com.jsg.pay.entity.DemoPayVo;
import org.apache.ibatis.annotations.Insert;

public interface DemoMapper {

    @Insert("insert into test_pay(id,money) values(null,${money})")
    int saveMoeny(DemoPayVo demoPayVo);
}

 

DemoBubboServiceImpl.java 服务的具体实现

package com.jsg.pay.dubbo.impl;

import com.jsg.pay.dubbo.DemoPayDubboService;
import com.jsg.pay.entity.DemoPayVo;
import com.jsg.pay.mybatisplus.mapper.DemoMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author: YangJie
 * @Date: 2021/1/15 3:08 下午
 */
//标注为dubbo服务 提供给其他服务调用
@DubboService
public class DemoBubboServiceImpl implements DemoPayDubboService {


    @Autowired
    private DemoMapper demoMapper;

    @Override
    public int saveMoney(DemoPayVo demoPayVo) {
        System.out.println("支付服务被调用");
        int test =  0;
        if(test == 0) {
            //throw new RuntimeException("发生异常了");//这里注释如果打开可以测试  用户服务保存成功 支付服务失败数据是否会回滚
        }
        return demoMapper.saveMoeny(demoPayVo);
    }
}

PayServiceApplication.java 启动类

package com.jsg;

import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @Author: YangJie
 * @Date: 2021/1/10 5:34 下午
 */
@SpringBootApplication
@EnableDiscoveryClient //启用nacos注册客户端
@EnableDubbo() //启用dubbo支持
@MapperScan("com.jsg.pay.mybatisplus.mapper") //mybatis扫描的Mapper接口
@EnableAutoDataSourceProxy //开启seata事务管理
public class PayServiceApplication {


    public static void main(String[] args) {
        SpringApplication.run(PayServiceApplication.class, args);

    }
}

 

 

 

 

 

-------------------------------------------------------用户服务-------------------------------------------------------

支付服务就算好了  接下来处理用户服务  pom.xml 以及yml配置   都跟支付服务都差不多

我这里就直接贴出来了

 

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>spring-cloud-module</artifactId>
        <groupId>com.jsg</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>

    <dependencies>

        <!-- 支付模块dubbo服务 -->
        <dependency>
            <groupId>com.jsg</groupId>
            <artifactId>pay-service-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.jsg</groupId>
            <artifactId>user-service-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- 数据库相关 开始-->
        <!-- mysql 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- mybatis plus 整合-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!-- 整合阿里的druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <!-- 数据库相关 结束-->


        <!-- web 应用(能够已jar或者war放tomca他的形式启动) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!-- spring cloud alibaba 整合nacos配置中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!-- spring cloud alibaba  整合nacos 服务注册/管理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- spring cloud alibaba 整合dubbo   -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

        <!-- 整合spring alibaba cloud的seata 开始
        需要排除 seata-spring-boot-starter 在引入 因为客户端版本可能不一致 我们使用的是1.4的服务端版本-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- 整合spring alibaba cloud的seata 结束 -->
        <!--  junit 测试所需的jar包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

bootstrap.yml

#抽取出nacos公共的配置 方便修改 启动配置中只配置nacos的 其他在application.yml中
nacos:
  service-address: 127.0.0.1:8848 #naocs地址需要带端口80也需要
  namespace: dev #nacos命名空间 比如dev 开发环境
  group: DEV_GROUP #nacos分组 比如 XXX业务组
  username: nacos
  password: nacos
  dubbo:
    namespace: dubbo #dubbo服务注册到nacos的命名空间
    group: DUBBO_GROUP #dubbo服务注册到nacos的组名
  seata:
    server: seata-server #这里必须和seata注册到nacos的服务名一样
    group: SEATA_GROUP #seata服务注册到nacos的组名SEATA_GROUP

#配置注册中心
spring:
  application:
    name: user-application #应用名字
  main:
    allow-bean-definition-overriding: true # 解决Bean重复定义问题
  cloud:
    nacos:
      discovery:
        server-addr: ${nacos.service-address} #nacos服务注册地址
        namespace: ${nacos.namespace} #nacos服务注册的命名空间
        group: ${nacos.group} #nacos服务注册的group
      config:
        server-addr: ${nacos.service-address} #nacos配置中心地址
        namespace: ${nacos.namespace} #nacos配置中心的命名空间
        group: ${nacos.group} #acos配置中心的group
        file-extension: yml #程序读取的主配置文件 拼接起来为payService.yml(spring.application.name+file-extension)
        extension-configs[0]: #第一个扩展配置(pay-application.yml有配置相同项将覆盖下面配置的 )
          data-id: common.yml #配置文件名字
          group: ${nacos.group} #配置文件所属分组
          refresh: true #是否动态刷新

application.yml

server:
  port: 8082
#数据源配置 使用啊里的druid
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/jsg_dev?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
      username: root
      password: 8#sOM6putB3HUy1Z


#dubbo配置也可以写在nacos中  如果有不同的这可以覆盖
dubbo:
  cloud:
    subscribed-services: pay-application #订阅的服务 多个以,隔开 默认*不建议会有警告
  scan:
    base-packages: com.jsg.user.dubbo.impl #注明dubbo扫描的包(有点像spring扫描包的配置该包下面的所有标注@DubboService的类都会扫描)
  application:
    #name: ${spring.application.name} #注入nacos的服务名
    # 禁用QOS同一台机器可能会有端口冲突现象
    qos-enable: false
    qos-accept-foreign-ip: false
  registry:
    address: nacos://${nacos.service-address} #dubbo服务注入nacos注册中心地址
    group: ${nacos.dubbo.group} #指定dubbo服务的组名
    parameters[namespace]: ${nacos.dubbo.namespace} #指定dubbo服务的命名空间
  protocol:
    port: -1 #自动生成端口号(从20880自增)
    name: dubbo
  consumer:
    check: false #启动检查服务是否存在(默认true),建议关闭,不然服务不存在有可能报错
    timeout: 4000 #设置超时时间 ms

#seata配置 更多配置参考 https://github.com/seata/seata/blob/1.4.0/script/client/spring/application.yml
seata:
  enabled: true #开启seata支持
  tx-service-group: my_test_tx_group #这里需要和config.txt 文件中的service.vgroupMapping.my_test_tx_group=default一致
  enable-auto-data-source-proxy: true
  #seata整合nacos配置中心
  config:
    type: nacos
    nacos:
      group: ${nacos.seata.group}
      server-addr: ${nacos.service-address}
      username: ${nacos.username}
      password: ${nacos.password}
  #seata整合nacos注册中心
  registry:
    type: nacos
    nacos:
      server-addr: ${nacos.service-address}
      username: ${nacos.username}
      password: ${nacos.password}
      application: ${nacos.seata.server} #这里必须和seata注册到nacos的服务名一样默认seata-server
      group: ${nacos.seata.group} #seata服务注册到nacos的组名SEATA_GROUP


#mybatis plus 配置
mybatis-plus:
  configuration:
    call-setters-on-nulls: true
    map-underscore-to-camel-case: true
    cache-enabled: false
  #    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-column-underline: true  #驼峰下划线转换
    capital-mode: true    #数据库大写下划线转换
    refresh-mapper: true  #刷新mapper 调试神器
    db-config:
      update-strategy: not_null #设置更新规则 null不更新
  mapper-locations: classpath*:/mapper/*Mapper.xml,classpath*:/mapper/*/*Mapper.xml #设置扫描mapper.xml的路径

写一个ctroller和service来测试调用支付服务 这里用户模块不作为dubbo其他服务的生产者  只是调用支付服务的消费者 ,结构如下

 

DemoUserMapper.java

package com.jsg.user.mybatisplus.mapper;

import org.apache.ibatis.annotations.Insert;

/**
 * @Author: YangJie
 * @Date: 2021/1/15 3:33 下午
 */
public interface DemoUserMapper {

    //简单测试一个保存操作
    @Insert("insert into test_user(id,name) values(null,'test')")
    int saveUser();
}

UserDemoService.java

package com.jsg.user.service;

import com.jsg.pay.dubbo.DemoPayDubboService;
import com.jsg.pay.entity.DemoPayVo;
import com.jsg.user.mybatisplus.mapper.DemoUserMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author: YangJie
 * @Date: 2021/1/15 3:33 下午
 */

//提供给crontller调用 使用spring的@Service 注解
@Service
public class UserDemoService {

    @DubboReference
    private DemoPayDubboService demoPayDubboService;

    @Autowired
    private DemoUserMapper demoUserMapper;

    public String saveUser(){
        int i = demoUserMapper.saveUser(); //简单的保存用户
        DemoPayVo demoPayVo = new DemoPayVo();
        demoPayVo.setMoney(22d);
        int j = demoPayDubboService.saveMoney(demoPayVo);
        if(i > 0 && j > 0){
            return "保存成功";
        }
        return "保存失败";
    }
}

 

TestContoller.java

package com.jsg.user.controller;

import com.jsg.pay.dubbo.PayDubboService;
import com.jsg.user.dubbo.UserLoginDubboService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: YangJie
 * @Date: 2021/1/10 7:31 下午
 */
@RestController
@RequestMapping("user")
public class TestContoller {

    @DubboReference()
    private UserLoginDubboService userLoginDubboService;


    @RequestMapping("/test.do")
    public String getName(){
        return  userLoginDubboService.saveUser();
    }
}

 

UserServiceApplication.java

package com.jsg;

import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @Author: YangJie
 * @Date: 2021/1/10 5:34 下午
 */
@SpringBootApplication
@EnableDiscoveryClient //启用nacos注册客户端
@EnableDubbo() //启用dubbo支持
@MapperScan("com.jsg.user.mybatisplus.mapper") //mybatis扫描的Mapper接口
@EnableAutoDataSourceProxy //开启seata事务管理
public class UserServiceApplication {


    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);

    }


}

 

启动项目pay-service 和user-service 查看nacos是否注入服务成功 如果启动有报错 参考最后 我这边也有遇到错误

 

注入成功 访问

http://localhost:8082/demo/save.do

报错io.netty.handler.codec.EncoderException: java.lang.IllegalStateException: Serialized class com.jsg.pay.entity.DemoPayVo must implement java.io.Serializable

支付模块传输vo实现一下Serializable接口在重启下两个服务

@Getter
@Setter
public class DemoPayVo  implements Serializable {

    private Double money;
}

在访问

看一下数据库是否有往两个表插入

实际业务里面  两个服务的表应该放在不同的数据库。我这里为了方便放在一起了。查看两个表 数据都成功插入

 

 

接下来在测试一下支付服务抛异常 支付服务已经保存的用户是否会回滚  为了方便查看数据 我先把数据库数据删除

打开DemoBubboServiceImpl.java 的注释 然后重启服务  并在抛异常之前打个断点

再次访问  发现user表还是插入成功了。发现未加分布式事务注解 @GlobalTransactional(rollbackFor = Exception.class)

 

 

重启服务 再次访问 发生异常   而且数据库 且user服务已经插入的行也被回滚。

 

 

数据库脚本

seata服务用到的表       每个业务模块都需要加该表 

CREATE TABLE `undo_log` (
  `branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(100) NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
  `log_created` datetime(6) NOT NULL COMMENT 'create datetime',
  `log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='AT transaction mode undo table';

 

test_pay表

CREATE TABLE `test_pay` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `money` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

test_user表

CREATE TABLE `test_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

 

 

启动报错

2021-01-13 11:50:54.882 ERROR 27707 --- [           main] i.s.c.r.netty.NettyClientChannelManager  : no available service found in cluster 'default', please make sure registry config correct and keep your seata server running


2021-01-13 15:39:41.601 ERROR 34411 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager  : 0304 register RM failed.

io.seata.common.exception.FrameworkException: can not connect to services-server.
	at io.seata.core.rpc.netty.NettyClientBootstrap.getNewChannel(NettyClientBootstrap.java:182) ~[seata-all-1.4.0.jar:1.4.0]
	at io.seata.core.rpc.netty.NettyPoolableFactory.makeObject(NettyPoolableFactory.java:58) ~[seata-all-1.4.0.jar:1.4.0]
	at io.seata.core.rpc.netty.NettyPoolableFactory.makeObject(NettyPoolableFactory.java:34) ~[seata-all-1.4.0.jar:1.4.0]

这是找不到seata服务 官方有说明

 

我按文档上的说明 

seata/bin/seata-server.sh -p 8091 -h 192.168.50.235 &

-p是指定端口 -h 是指定IP 现在好像还不支持域名 启动后就OK了,如果你是在一台机器上测试 不用改这个

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值