• 分布式事务Seata


    由于目前互联网企业的兴起,越来越多的企业开始采用微服务架构模式。微服务架构模式的确提升后台服务的性能,保证服务的高可用等优点,但是同时也带来了一个问题,即如何保证数据的一致性、操作原子性,即分布式事务。目前,互联网主要有2PC,3PC,TCC,事务性事务方式。 今天就主要介绍阿里旗下的分布式事务中间件Seata

    1.Seata地址:https://github.com/seata/seata/issues ,下载seata-server

    2.将Seata放到相应的文件目录解压,并修改conf文件夹下,修改registry.conf以及file.conf

    3.修改registry.conf,以文件格式注册

    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      type = "file"
    
      file {
        name = "file.conf"
      }
    }
    
    config {
      # file、nacos 、apollo、zk、consul、etcd3
      type = "file"
    
      file {
        name = "file.conf"
      }
    }
    

    4.修改file.conf,以文件形式时,需要通过netty通信 

    transport {
      # tcp udt unix-domain-socket
      type = "TCP"
      #NIO NATIVE
      server = "NIO"
      #enable heartbeat
      heartbeat = true
      #thread factory for netty
      threadFactory {
        bossThreadPrefix = "NettyBoss"
        workerThreadPrefix = "NettyServerNIOWorker"
        serverExecutorThreadPrefix = "NettyServerBizHandler"
        shareBossWorker = false
        clientSelectorThreadPrefix = "NettyClientSelector"
        clientSelectorThreadSize = 1
        clientWorkerThreadPrefix = "NettyClientWorkerThread"
        # netty boss thread size,will not be used for UDT
        bossThreadSize = 1
        #auto default pin or 8
        workerThreadSize = "8"
      }
      serialization = "seata"
      compressor = "none"
    }
    
    ## transaction log store, only used in server side
    store {
      ## store mode: file、db
      mode = "file"
      ## file store property
      file {
        ## store location dir
        dir = "sessionStore"
        # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
        maxBranchSessionSize = 16384
        # globe session size , if exceeded throws exceptions
        maxGlobalSessionSize = 512
        # file buffer size , if exceeded allocate new buffer
        fileWriteBufferCacheSize = 16384
       # when recover batch read size
        sessionReloadReadSize = 100
        # async, sync
        flushDiskMode = async
      }
    
      ## database store property
      db {
        ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
        datasource = "druid"
        ## mysql/oracle/postgresql/h2/oceanbase etc.
        dbType = "mysql"
        driverClassName = "com.mysql.jdbc.Driver"
        url = "jdbc:mysql://192.168.2.172:3306/seata"
        user = "root"
        password = "root"
        global.table = "global_table"
        branch.table="branch_table"
        query-limit = 100
      }
    }
    

    5.java代码,首先启动Eureka,然后,在Account服务中,写服务

    package com.example.account.controller;
    
    
    import com.example.account.service.ISeataAccountService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.math.BigDecimal;
    
    /**
     * <p>
     * 账户信息表 前端控制器
     * </p>
     *
     * @author yz
     * @since 2020-04-28
     */
    @RestController
    @RequestMapping("/account")
    public class SeataAccountController {
    
        @Autowired
        private ISeataAccountService accountService;
    
        @RequestMapping("/deduction")
        public void deduction(@RequestParam("id") Integer accountId,@RequestParam("price") BigDecimal money)  {
            accountService.deduction(accountId, money);
    //        throw new RuntimeException("错误");
        }
    }
    

      6.在Order服务中远程调用 

    package com.example.orderservice.service;
    
    import com.example.orderservice.service.impl.AccountService;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import java.math.BigDecimal;
    
    @FeignClient(name="account-service",fallback = AccountService.class)
    public interface IAccountService {
    
        @RequestMapping(value = "/account/deduction",method = RequestMethod.GET)
        void deduction(@RequestParam("id") Integer accountId,@RequestParam("price") BigDecimal money);
    }
    

      

    package com.example.orderservice.controller;
    
    
    import com.example.orderservice.entity.SeataOrder;
    import com.example.orderservice.service.IAccountService;
    import com.example.orderservice.service.ISeataOrderService;
    import io.seata.spring.annotation.GlobalTransactional;
    import org.apache.commons.lang.math.RandomUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.math.BigDecimal;
    import java.util.Random;
    
    /**
     * <p>
     * 前端控制器
     * </p>
     *
     * @author yz
     * @since 2020-04-28
     */
    @RestController
    @RequestMapping("/order")
    public class SeataOrderController {
    
        @Autowired
        IAccountService accountService;
    
        @Autowired
        ISeataOrderService orderService;
    
        @RequestMapping("/submit")
        @GlobalTransactional
        public void submitOrder(@RequestParam("id") Integer accountId,@RequestParam("price") BigDecimal orderPrice) {
            accountService.deduction(accountId, orderPrice);
            SeataOrder order = new SeataOrder();
            order.setOAccountId(accountId);
            order.setOGoodId(RandomUtils.nextInt());
            order.setOPrice(orderPrice.intValue());
            orderService.save(order);
    //        throw new RuntimeException("错误");
            System.out.println("成功");
        }
    }
    

      7.需要在Order和Account服务端中的resources中添加file.conf

      service {
        vgroupMapping.minbox-seata = "seata-server"
        seata-server.grouplist = "192.168.2.172:8091"
        enableDegrade = false
        disable = false
      }
    
      client {
        async.commit.buffer.limit = 10000
        lock {
          retry.internal = 10
          retry.times = 30
        }
    }
    

      以上操作就可以实现分布式事务

    另外 ,也可以将seata-server注入到eureka中,来使用

    registry.conf

    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      type = "eureka"
    
    
       eureka {
         serviceUrl = "http://192.168.2.242:8090/eureka/"
         application = "seata-server"
         weight = "1"
      }
    }
    

     file.conf

    store {
      ## store mode: file、db
      mode = "file"
      ## file store property
      file {
        ## store location dir
        dir = "sessionStore"
        # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
        maxBranchSessionSize = 16384
        # globe session size , if exceeded throws exceptions
        maxGlobalSessionSize = 512
        # file buffer size , if exceeded allocate new buffer
        fileWriteBufferCacheSize = 16384
       # when recover batch read size
        sessionReloadReadSize = 100
        # async, sync
        flushDiskMode = async
      }
    
    }
    

      就可以实现分布式事务了

     启动Seata-server:./seata-server.sh

  • 相关阅读:
    分苹果
    马拉车算法(求最长回文子串)
    KMP
    字典树
    关于子类和父类中的this的用法
    最长上生子序列LIS
    sass
    黑马程序员----java基础笔记下(毕向东)
    DOM
    ajax教程
  • 原文地址:https://www.cnblogs.com/jimmy109/p/12800469.html
Copyright © 2020-2023  润新知