分布式事务解决方案--seata AT模式(spring cloud eureka+fegin+seata)

一.整体搭建准备

   一.1.下载seata-server服务端(地址:https://seata.io/zh-cn/blog/download.html)

    一.2. 修改seata-serve里面的配置file.conf文件,file.conf.example文件,以及registry.conf文件

    一.3. 从githhub下载好准备好的demo,然后配更改好demo里的一些配置文件(改成自己本地的即可)

            demo地址(https://github.com/chengshugithub/springcloud-eureka-feign-seata)

    一.4. 运行 eureka的服务端,然后运行seata-server,然后继续运行我们demo里面的三个服务;

二.先通过官网下载 seata-server(地址:https://seata.io/zh-cn/blog/download.html)

   二.1.下载之后,我们进行解压然后找到如下图三个文件进行修改


 我的file.conf文件配置

这里我采用的是db方式,连接是mysql;自己改成自己本机的mysql的用户名密码和驱动

## transaction log store, only used in seata-server

store {

  ## store mode: file、db、redis

 #这里的话选择是db,级寻找下面的db配置,这里我用的是mysql;

  mode = "db"

  ## 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)/HikariDataSource(hikari) etc.

    datasource = "dbcp"

    ## mysql/oracle/postgresql/h2/oceanbase etc.

    dbType = "mysql"

    driverClassName = "com.mysql.cj.jdbc.Driver"

    url = "jdbc:mysql://127.0.0.1:3306/seata-server?serverTimezone=GMT%2B8"

    user = "root"

    password = "root"

    minConn = 5

    maxConn = 100

    globalTable = "global_table"

    branchTable = "branch_table"

    lockTable = "lock_table"

    queryLimit = 100

    maxWait = 5000

  }

  ## redis store property

  redis {

    host = "127.0.0.1"

    port = "6379"

    password = ""

    database = "0"

    minConn = 1

    maxConn = 10

    maxTotal = 100

    queryLimit = 100

  }

}

## metrics configuration, only used in server side

metrics {

  enabled = false

  registryType = "compact"

  # multi exporters use comma divided

  exporterList = "prometheus"

  exporterPrometheusPort = 9898

}

  我的file.conf.example文件配置

   需要注意的是 service里面的配置  vgroupMapping.my_test_tx_group = "default";

                                                           default.grouplist = "127.0.0.1:8091"

transport {

  # tcp udt unix-domain-socket

  type = "TCP"

  #NIO NATIVE

  server = "NIO"

  #enable heartbeat

  heartbeat = true

  # the client batch send request enable

  enableClientBatchSendRequest = true

  #thread factory for netty

  threadFactory {

    bossThreadPrefix = "NettyBoss"

    workerThreadPrefix = "NettyServerNIOWorker"

    serverExecutorThread-prefix = "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 = "default"

  }

  shutdown {

    # when destroy server, wait seconds

    wait = 3

  }

  serialization = "seata"

  compressor = "none"

}

service {

  #transaction service group mapping

  vgroupMapping.my_test_tx_group = "default"

  #only support when registry.type=file, please don't set multiple addresses

  default.grouplist = "127.0.0.1:8091"

  #degrade, current not support

  enableDegrade = false

  #disable seata

  disableGlobalTransaction = false

}

client {

  rm {

    asyncCommitBufferLimit = 10000

    lock {

      retryInterval = 10

      retryTimes = 30

      retryPolicyBranchRollbackOnConflict = true

    }

    reportRetryCount = 5

    tableMetaCheckEnable = false

    reportSuccessEnable = false

  }

  tm {

    commitRetryCount = 5

    rollbackRetryCount = 5

  }

  undo {

    dataValidation = true

    logSerialization = "jackson"

    logTable = "undo_log"

  }

  log {

    exceptionRate = 100

  }

}


 我的registry.conf文件配置

这个注册的话,采用的是eureka的配置;这里会把seata服务注册到eureka;

registry {

  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa

  type = "eureka"

  loadBalance = "RandomLoadBalance"

  loadBalanceVirtualNodes = 10

  nacos {

    application = "seata-server"

    serverAddr = "127.0.0.1:8848"

    group = "SEATA_GROUP"

    namespace = ""

    cluster = "default"

    username = ""

    password = ""

  }

  eureka {

    serviceUrl = "http://localhost:8761/eureka"

    application = "default"

    weight = "1"

  }

  redis {

    serverAddr = "localhost:6379"

    db = 0

    password = ""

    cluster = "default"

    timeout = 0

  }

  zk {

    cluster = "default"

    serverAddr = "127.0.0.1:2181"

    sessionTimeout = 6000

    connectTimeout = 2000

    username = ""

    password = ""

  }

  consul {

    cluster = "default"

    serverAddr = "127.0.0.1:8500"

  }

  etcd3 {

    cluster = "default"

    serverAddr = "http://localhost:2379"

  }

  sofa {

    serverAddr = "127.0.0.1:9603"

    application = "default"

    region = "DEFAULT_ZONE"

    datacenter = "DefaultDataCenter"

    cluster = "default"

    group = "SEATA_GROUP"

    addressWaitTime = "3000"

  }

  file {

    name = "file.conf"

  }

}

config {

  # file、nacos 、apollo、zk、consul、etcd3

  type = "file"

  nacos {

    serverAddr = "127.0.0.1:8848"

    namespace = ""

    group = "SEATA_GROUP"

    username = ""

    password = ""

  }

  consul {

    serverAddr = "127.0.0.1:8500"

  }

  apollo {

    appId = "seata-server"

    apolloMeta = "http://192.168.1.204:8801"

    namespace = "application"

    apolloAccesskeySecret = ""

  }

  zk {

    serverAddr = "127.0.0.1:2181"

    sessionTimeout = 6000

    connectTimeout = 2000

    username = ""

    password = ""

  }

  etcd3 {

    serverAddr = "http://localhost:2379"

  }

  file {

    name = "file.conf"

  }

}

二.2.接下来创建seata所需要的的数据库和表;

根据 file.conf文件里面的db连接的数据库名,当然自己可以随便改名;

我们需要创建三个表,这个表是给seata-server用的;

需要以下三张表;建表sql如下;

CREATE TABLE `branch_table` (

  `branch_id` bigint(20) NOT NULL,

  `xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

  `transaction_id` bigint(20) NULL DEFAULT NULL,

  `resource_group_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `branch_type` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `status` tinyint(4) NULL DEFAULT NULL,

  `client_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `gmt_create` datetime(6) NULL DEFAULT NULL,

  `gmt_modified` datetime(6) NULL DEFAULT NULL,

  PRIMARY KEY (`branch_id`) USING BTREE,

  INDEX `idx_xid`(`xid`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for global_table

-- ----------------------------

DROP TABLE IF EXISTS `global_table`;

CREATE TABLE `global_table`  (

  `xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

  `transaction_id` bigint(20) NULL DEFAULT NULL,

  `status` tinyint(4) NOT NULL,

  `application_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `transaction_service_group` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `transaction_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `timeout` int(11) NULL DEFAULT NULL,

  `begin_time` bigint(20) NULL DEFAULT NULL,

  `application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `gmt_create` datetime(0) NULL DEFAULT NULL,

  `gmt_modified` datetime(0) NULL DEFAULT NULL,

  PRIMARY KEY (`xid`) USING BTREE,

  INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,

  INDEX `idx_transaction_id`(`transaction_id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for lock_table

-- ----------------------------

DROP TABLE IF EXISTS `lock_table`;

CREATE TABLE `lock_table`  (

  `row_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

  `xid` varchar(96) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `transaction_id` bigint(20) NULL DEFAULT NULL,

  `branch_id` bigint(20) NOT NULL,

  `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `table_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `pk` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  `gmt_create` datetime(0) NULL DEFAULT NULL,

  `gmt_modified` datetime(0) NULL DEFAULT NULL,

  PRIMARY KEY (`row_key`) USING BTREE,

  INDEX `idx_branch_id`(`branch_id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;


二.2此时去github上down我们的项目(地址:https://github.com/chengshugithub/springcloud-eureka-feign-seata);

   @1然后每个服务下面都有创建自己表的sql语句;然后根据配置文件去创建每个服务的库;

   @2 我们服务的事物提交主要是通过seata服务去提交这个全局的事物,每一个服务的数据库都需要去创建一张这个表,sql如下;

CREATE TABLE `undo_log` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `branch_id` bigint(20) NOT NULL,

  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

  `rollback_info` longblob NOT NULL,

  `log_status` int(11) NOT NULL,

  `log_created` datetime(0) NOT NULL,

  `log_modified` datetime(0) NOT NULL,

  `ext` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

  PRIMARY KEY (`id`) USING BTREE,

  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

 @3然后每个服务下面都需要去增加file.conf和regist.conf文件,这个regist.conf文件其实就是seata-server下的file.conf.example的文件;具体的在项目里面看;


@4 总结一下:如果想把自己的项目整合到seata-server管理。

       @4.1 引入setata依赖:(因为依赖放在这格式会乱,所以就不放了)

      @4.2  resources下配置file.conf文件和 registry.conf文件;

      @4.3 数据库里面增加一个undo_log的表;

      @4.4 修改配置文件,如下:


     @4.5 数据源交给setata代理处理;(代码上有)

    @4.6  然后代码块使用@GlobalTransactional注解

三.此时我们再进行运行程序;

   1.启动 eureka-server

   2.启动 seatea-serer

   3.陆续启动自己demo的三个服务;

  4.http://localhost:8180/order/create?userId=1&productId=1&count=10&money=100;

( 逻辑的话自己看就好了,基本上是订单调用库存,库存减少,账户减少)

你可能感兴趣的:(分布式事务解决方案--seata AT模式(spring cloud eureka+fegin+seata))