zoukankan      html  css  js  c++  java
  • springboot2整合seata(AT模式)

    1.启动seata服务

    docker启动seata-server实例,使用1.3.0版本

    docker pull seataio/seata-server:1.3.0
    docker run --name seata-server -p 8091:8091 seataio/seata-server
    

    2.创建三个项目实现下订单、库存减少分布式事物

    dkn-provider-order 下订单服务
    dkn-provider-store 库存服务
    dkn-shop 模拟用户购买商品服务

    1.dkn-provider-orde和dkn-provider-store的pom.xml

    <dependencyManagement>
      <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.3.8.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
    </dependencyManagement>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-seata</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    

    2.yml配置文件 dkn-provider-orde和dkn-provider-store

    端口,服务名称、数据库信息,application-id需要换下

    server:
      port: 9102
    spring:
      application:
        name: dkn-provider-order
      datasource:
        druid:
          url: jdbc:mysql://localhost:3306/dkn-provider-order?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
          driverClassName: com.mysql.cj.jdbc.Driver
          username: root
          password: root
    
    seata:
      enabled: true
      application-id: dkn-provider-order
      tx-service-group: dkn_tx_group
      enable-auto-data-source-proxy: false   #一定要是false
      service:
        vgroup-mapping:
          dkn_tx_group: default  #key与上面的tx-service-group的值对应
        grouplist:
          default: 10.0.0.70:8091 #seata-server地址仅file注册中心需要
      config:
        type: file
      registry:
        type: file
    
    logging:
      level:
        com.dkn: debug
    
    

    3.SeataConfig配置,这个都一样,dkn-shop不需要添加

    @Configuration
    public class SeataConfig {
    
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.druid")
        public DataSource druidDataSource(){
            DruidDataSource druidDataSource = new DruidDataSource();
            return druidDataSource;
        }
    
        @Primary
        @Bean("dataSource")
        public DataSourceProxy dataSource(DataSource druidDataSource){
            return new DataSourceProxy(druidDataSource);
        }
    
    }
    
    

    4.service和controller

    @Service
    public class DknOrderServiceImpl extends ServiceImpl<DknOrderMapper,DknOrder> implements DknOrderService {
    
        @Override
        public boolean add(Integer productid, Integer num) {
            DknOrder dknOrder=new DknOrder();
            dknOrder.setNum(num);
            dknOrder.setProductid(productid);
    
            return this.save(dknOrder);
        }
    }
    
    @Service
    public class StoreServiceImpl extends ServiceImpl<StoreMapper,Store> implements StoreService {
    
        @Override
        public boolean reduce(Integer productid,Integer n) {
            UpdateWrapper<Store> updateWrapper=new UpdateWrapper<Store>();
            updateWrapper.setSql("num = num - "+n);
            updateWrapper.eq("productid", productid);
            return this.update(updateWrapper);
        }
    }
    
    @RestController
    @RequestMapping("/Order")
    public class DknOrderController {
    
    	@Autowired
    	private DknOrderService dknOrderService;
    
    	@GetMapping("add")
    	public AjaxResult add(Integer productid, Integer num){
    		boolean result=dknOrderService.add(productid,num);
    		if(result){
    			return AjaxResult.success();
    		}else{
    			return AjaxResult.error();
    		}
    	}
    	
    }
    
    @RestController
    @RequestMapping("/Store")
    public class StoreController {
    
    	@Autowired
    	private StoreService storeService;
    	
    	@GetMapping("reduce")
    	public AjaxResult reduce(Integer productid,Integer num){
    		boolean result=storeService.reduce(productid,num);
    		if(result){
    			return AjaxResult.success();
    		}else{
    			return AjaxResult.error();
    		}
    	}
    
    }
    
    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    public class OrderApplication {
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    }
    
    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    public class StoreApplication {
        public static void main(String[] args) {
            SpringApplication.run(StoreApplication.class, args);
        }
    }
    

    5.dkn-shop配置

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-seata</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    
    server:
      port: 9100
    spring:
      application:
        name: dkn-shop
    
    seata:
      enabled: true
      application-id: dkn-shop
      tx-service-group: dkn_tx_group
      enable-auto-data-source-proxy: false   #一定要是false
      service:
        vgroup-mapping:
          dkn_tx_group: default  #key与上面的tx-service-group的值对应
        grouplist:
          default: 10.0.0.70:8091 #seata-server地址仅file注册中心需要
      config:
        type: file
      registry:
        type: file
    
    #开启使用 httpclient
    feign:
      httpclient:
        enabled: true
    
    logging:
      level:
        com.dkn: debug
        org.apache.http: debug
    
    @EnableFeignClients
    @SpringBootApplication
    public class ShopApplication {
        public static void main(String[] args) {
            SpringApplication.run(ShopApplication.class, args);
        }
    }
    
    @FeignClient(name="dkn-provider-order", url = "http://localhost:9102")
    @Service
    public interface OrderService {
        @GetMapping("/Order/add")
        public AjaxResult add(@RequestParam(name = "productid") Integer productid, @RequestParam(name = "num") Integer num);
    
    }
    
    @FeignClient(name="dkn-provider-store", url = "http://localhost:9101")
    @Service
    public interface StoreService {
        @GetMapping("/Store/reduce")
        public AjaxResult reduce(@RequestParam(name = "productid") Integer productid, @RequestParam(name = "num") Integer num);
    
    }
    
    @Service
    public class ShopService {
    
        @Autowired
        OrderService orderService;
    
        @Autowired
        StoreService storeService;
    
        @GlobalTransactional
        public void buy(Integer productid,Integer num){
            orderService.add(productid,num);
            storeService.reduce(productid,num);
        }
    
        @GlobalTransactional
        public void buyError(Integer productid,Integer num){
            orderService.add(productid,num);
            int a=1/0;
            storeService.reduce(productid,num);
        }
    
    }
    
    @RestController
    @RequestMapping("/Shop")
    public class ShopController {
    
    	@Autowired
    	private ShopService shopService;
    
    	//测试正常  http://localhost:9100/Shop/buy?productid=101&num=2
    	@GetMapping("buy")
    	public AjaxResult buy(Integer productid, Integer num){
    		shopService.buy(productid,num);
    		return AjaxResult.success();
    	}
    
    	//测试错误  http://localhost:9100/Shop/buy?productid=101&num=2
    	@GetMapping("buyError")
    	public AjaxResult buyError(Integer productid, Integer num){
    		shopService.buyError(productid,num);
    		return AjaxResult.success();
    	}
    }
    

    6.数据库文件

    -- ----------------------------
    -- Table structure for store
    -- ----------------------------
    DROP TABLE IF EXISTS `store`;
    CREATE TABLE `store` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
      `productid` int(11) DEFAULT NULL COMMENT '商品id',
      `productname` varchar(255) DEFAULT NULL COMMENT '商品名称',
      `num` int(11) DEFAULT NULL COMMENT '库存数量',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of store
    -- ----------------------------
    INSERT INTO `store` VALUES ('1', '101', '笔记本', '100');
    
    -- ----------------------------
    -- Table structure for undo_log
    -- ----------------------------
    DROP TABLE IF EXISTS `undo_log`;
    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,
      `ext` varchar(100) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of undo_log
    -- ----------------------------
    
    -- ----------------------------
    -- Table structure for dkn_order
    -- ----------------------------
    DROP TABLE IF EXISTS `dkn_order`;
    CREATE TABLE `dkn_order` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
      `productid` int(11) DEFAULT NULL COMMENT '商品id',
      `num` int(11) DEFAULT NULL COMMENT '购买数量',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of dkn_order
    -- ----------------------------
    
    -- ----------------------------
    -- Table structure for undo_log
    -- ----------------------------
    DROP TABLE IF EXISTS `undo_log`;
    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,
      `ext` varchar(100) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
    
    
  • 相关阅读:
    Windows进程端口相关命令
    SpringMVC获取请求的匹配方法对应的路径
    Feign配置远程调用时携带原请求的token
    LINUX的patch文件 何打patch
    如何制作LINUX的patch文件及如何打patch
    (转) 跟我一起写 Makefile --- 陈皓
    u-boot移植到mini2440,增加DM9000驱动的学习笔记
    DNW PL2303驱动解决问题
    kermit的安装,配置
    wpf中bool按钮三种方式
  • 原文地址:https://www.cnblogs.com/daikainan/p/14418886.html
Copyright © 2011-2022 走看看