• nacos-高可用seata之TC搭建(02)


    准备阶段(Prepare phase): 事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,此时事务没有提交。 ( Undo日志是记录修改前的数据,用于数据库回滚, Redo日志是记录修改后的数据,用于提交事务后写入数 据文件) ​ ​ 提交阶段(commit phase): 如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。注意:必须在最后阶段释放锁资源。

     

     

    
    #创建数据库
     create database mydemo1;
     
     use mydemo1;
     
     create table orders(id int primary key not null auto_increment,orderdate date,shopid int not null,buynum int not null);
    ​

     

    mybaits-plus自动生成

    package com.kgc.mynacos02.ordermodule;
    ​
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.generator.AutoGenerator;
    import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
    import com.baomidou.mybatisplus.generator.config.GlobalConfig;
    import com.baomidou.mybatisplus.generator.config.PackageConfig;
    import com.baomidou.mybatisplus.generator.config.StrategyConfig;
    import com.baomidou.mybatisplus.generator.config.rules.DateType;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    ​
    public class GeneratorCode {
        public static void main(String[] args) {
            AutoGenerator ag = new AutoGenerator();
    //        //开启连接数据库
            DataSourceConfig dsc = new DataSourceConfig();
            dsc.setUrl("jdbc:mysql://192.168.64.135:3306/mydemo1");
            dsc.setDriverName("com.mysql.jdbc.Driver");
            dsc.setUsername("root");
            dsc.setPassword("3090_Cmok");
            ag.setDataSource(dsc);
    ​
            //设置全局配置
            GlobalConfig gc = new GlobalConfig();
            gc.setOutputDir(System.getProperty("user.dir")+"/mynacos02-ordermodule/src/main/java");
            gc.setAuthor("js");
            gc.setFileOverride(true);
            gc.setOpen(false);
            gc.setMapperName("%sMapper");//OrderMapper
            gc.setXmlName("%sMapper");//OrderMapper.xml
            gc.setServiceName("%sService");//Service
            gc.setServiceImplName("%sServiceImpl");
            gc.setControllerName("%sCtrl");
    ​
            ag.setGlobalConfig(gc);
    ​
            //设置包名
            PackageConfig pc = new PackageConfig();
            pc.setParent("com.kgc.mynacos02.ordermodule");
            pc.setMapper("mapper");
            pc.setEntity("domain");
            pc.setController("controller");
            pc.setService("services");
            pc.setServiceImpl("services.impl");
            //设置每个类的主键方式
            gc.setIdType(IdType.AUTO);
            //设置日期类型
            gc.setDateType(DateType.ONLY_DATE);
            ag.setPackageInfo(pc);
            //设置策略
            StrategyConfig sc = new StrategyConfig();
            sc.setEntityLombokModel(true);
            sc.setRestControllerStyle(true);
            sc.setColumnNaming(NamingStrategy.underline_to_camel);
            sc.setNaming(NamingStrategy.underline_to_camel);
            ag.setStrategy(sc);
            ag.execute();
        }
    }
    ​

    第一步导入pom依赖

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    <!--        //导入mybaitis核心-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.2</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>3.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity</artifactId>
                <version>1.7</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.9</version>
            </dependency>
            <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>

    第二步配置remote接口

    @FeignClient(value = "stockmodule",path = "stock")
    public interface StockFeignService {
        @GetMapping(value = "/deduct/{shopid}/{num}")
        public String deduct(@PathVariable("shopid")Integer shopid, @PathVariable("num") Integer num);
    ​
    }
    ​

    第三步配置实体类 (domain service controller)

    #domain
    @Data
    @Builder
      @EqualsAndHashCode(callSuper = false)
        public class Orders implements Serializable {
    ​
        private static final long serialVersionUID = 1L;
    ​
          @TableId(value = "id", type = IdType.AUTO)
          private Integer id;
    ​
        private Date orderdate;
    ​
        private Integer shopid;
    ​
        private Integer buynum;
    ​
    ​
    }
    ​
    #service接口
    public interface OrdersService extends IService<Orders> {
        void ordHndler(Orders ord);
    }
    #service接口实现类
    @Service
    public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
        @Resource
        private StockFeignService stockFeignService;
        @Override
        @Transactional
        public void ordHndler(Orders ord){
            //把订单存放到mydemo1数据库的orders表中
            save(ord);
            stockFeignService.deduct(ord.getShopid(),ord.getBuynum());
        }
    }
    ​
    #controller
    @RestController
    @RequestMapping("/orders")
    public class OrdersCtrl {
        @Resource
        private OrdersService os;
    ​
        @RequestMapping(value = "/addOrder",method = RequestMethod.GET)
        public String addOrder(@RequestParam("shopid") int shopid,@RequestParam("buynum") int buynum){
            Orders ord = Orders.builder().orderdate(new Date()).shopid(shopid).buynum(buynum).build();
            os.ordHndler(ord);
            return "SUCCESS";
        }
    }
    ​
    #application配置注解
    @SpringBootApplication
    @EnableFeignClients
    @MapperScan("com.kgc.mynacos02.ordermodule.mapper")
    public class OrderApplication {
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class,args);
        }
    }

    启动订单 和库存2个服务!!!

    postman远程调用接口

    Seata**安装(史上最细 包成功!!)

    准备一下2个jar包 放到opt目录下

     

    cd /opt/
    ​
    ls
    ​
    tar -zxf seata-server-1.3.0.tar.gz
    ​
    mv seata soft/seata
    ​
    cd soft/seata/conf
    ​
    vim file.conf
    #修改4个数据 mode="db" serverAddr 自己的地址 账号密码
    ​
    cd /opt/
    ​
    mkdir sta
    ​
    mv seata-1.3.0.zip sta/
    ​
    cd sta/
    ​
    yum install -y unzip zip
    ​
    unzip seata-1.3.0.zip
    ​
    cd seata-1.3.0
    ​
    ls
    ​
    mysql -uroot -p3090_Cmok
    ​
    create database seata;
    ​
    use seata;
    ​
    source /opt/sta/seata-1.3.0/script/server/db/mysql.sql
    ​
    exit;
    ​
    cd /opt/soft/seata/conf
    ​
    vim registry.conf
    #修改type = "nacos"  serverAddr你的地址 账号nacos密码nacos
    #修改config type = "nacos"  账号nacos密码nacos
    #一共改7个
    :wq
    ​
    cd /opt
    ​
    ls
    ​
    cd sta/seata-1.3.0/script/config-center/
    ​
    vim config.txt
    ​
    #service.vgroupMapping.my_test_tx_group=default
    #my_test_tx_group这个为真实机房地址 可以改成nanjing
    ##事务分组 异地机房停电可以切换 在后期client调用时候使用 seata.service.vgroup- mapping.projectA=自己
    #修改4个地方
    service.vgroupMapping.nanjing=default
    store.db.url=jdbc:mysql://192.168.64.135:3306/
    store.db.user=root
    store.db.password=3090_Comk
    #保存退出
    :wq
    ​
    cd nacos/
    ​
    ls
    ​
    ll
    ​
    #将config.txt文件上传到配置中心
    sh nacos-config.sh -h 192.168.64.135 -p 8848 -g SEATA_GROUP
    ​
    cd /opt/soft/seata/bin/
    ​
    ls
    ​
    #启动seata server
    ./seata-server.sh -p 9009 -n 1
    ​

     

    打开浏览器!

    192.168.64.135:8848/nacos

     

    出现以上界面表明安装成功!!

    1)启动Seata server端,Seata server使用nacos作为配置中心和注册中心(上一步已完成) 2)

    第一步配置微服务整合seata

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

    第二步: 各微服务对应数据库中添加undo_log表

    mysql -uroot -p3090_Cmok
    ​
    use mydemo;
    #执行下面建表
    #====================================
    CREATE TABLE `undo_log` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `branch_id` bigint(20) NOT NULL,
    `xid` varchar(100) NOT NULL,
    `context` varchar(128) NOT NULL,
    `rollback_info` longblob NOT NULL,
    `log_status` int(11) NOT NULL,
    `log_created` datetime NOT NULL,
    `log_modified` datetime NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    #====================================
    use mydemo1;
    #同理

    第三步:修改application.yml配置(2边都加)

    server:
      port: 8003
    spring:
      application:
        name: ordermodule
      datasource:
        druid:
          url: jdbc:mysql://192.168.64.135:3306/mydemo1?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true
          username: root
          password: 3090_Cmok
          initial-size: 3
          max-active: 30
          min-idle: 3
          max-wait: 60000
          time-between-eviction-runs-millis: 60000
          min-evictable-idle-time-millis: 300000
          validation-query: select 1
          test-on-borrow: true
          test-while-idle: false
          test-on-return: false
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 30
          filter: stat,wall
          connection-properties: druid.stat.mergeSql=true;druid.stat.slowSq1Millis=500
          use-global-data-source-stat: true
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.64.135:8848
            username: nacos
            password: nacos
            namespace: public
        alibaba:
          seata:
            tx-service-group: nanjing
    mybatis-plus:
      mapper-locations: mapper/*.xml
    seata:
      registry:
        type: nacos
        nacos:
          server-addr: 192.168.64.135:8848
          username: nacos
          password: nacos
          application: seata-server
      config:
        type: nacos
        nacos:
          server-addr: 192.168.64.135:8848
          username: nacos
          password: nacos
          group: SEATA_GROUP
          namespace: public

     

    postman测试(需要在service实现类中 自定义异常)

     

    查询数据库(库存没减回滚成功!!!)

     

  • 相关阅读:
    【数学建模暑期培训】线性回归模型
    Elasticsearch Relevance Engine---为AI变革提供高级搜索能力[ES向量搜索、常用配置参数、聚合功能等详解]
    这次轮到微软炸场了;5000+AI工具调研报告 (500万字);狂打一星开喷AI聊天机器人;CMU LLM课程;AI创业的方向与时机 | ShowMeAI日报
    [附源码]计算机毕业设计JAVAjsp旅游景点管理系统
    window和linux下载ffmpeg
    Vue自定义指令
    vue动态数据在列表展示
    备战金九银十,4面顺利拿下offer
    Visual Studio Code使用
    redis的原理和源码-发布订阅
  • 原文地址:https://blog.csdn.net/just_learing/article/details/125625422