SEATA Server Configure

  1. 下载 seata-server

  2. 创建数据库(seata),可自定义,在file.conf中要用到。

    -- -------------------------------- The script used when storeMode is 'db' --------------------------------
    -- the table to store GlobalSession data
    CREATE TABLE IF NOT EXISTS `global_table`
    (
    `xid` VARCHAR(128) NOT NULL,
    `transaction_id` BIGINT,
    `status` TINYINT NOT NULL,
    `application_id` VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name` VARCHAR(128),
    `timeout` INT,
    `begin_time` BIGINT,
    `application_data` VARCHAR(2000),
    `gmt_create` DATETIME,
    `gmt_modified` DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
    ) ENGINE = InnoDB
    DEFAULT CHARSET = utf8; -- the table to store BranchSession data
    CREATE TABLE IF NOT EXISTS `branch_table`
    (
    `branch_id` BIGINT NOT NULL,
    `xid` VARCHAR(128) NOT NULL,
    `transaction_id` BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id` VARCHAR(256),
    `branch_type` VARCHAR(8),
    `status` TINYINT,
    `client_id` VARCHAR(64),
    `application_data` VARCHAR(2000),
    `gmt_create` DATETIME,
    `gmt_modified` DATETIME,
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
    ) ENGINE = InnoDB
    DEFAULT CHARSET = utf8; -- the table to store lock data
    CREATE TABLE IF NOT EXISTS `lock_table`
    (
    `row_key` VARCHAR(128) NOT NULL,
    `xid` VARCHAR(96),
    `transaction_id` BIGINT,
    `branch_id` BIGINT NOT NULL,
    `resource_id` VARCHAR(256),
    `table_name` VARCHAR(32),
    `pk` VARCHAR(36),
    `gmt_create` DATETIME,
    `gmt_modified` DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
    ) ENGINE = InnoDB
    DEFAULT CHARSET = utf8;
  3. 编辑file.conf配置文件

    service {
    #transaction service group mapping
    vgroup_mapping.sunrise_tx_group = "default"
    #only support when registry.type=file, please don't set multiple addresses
    default.grouplist = "127.0.0.1:8091"
    #disable seata
    disableGlobalTransaction = false
    #degrade current not support
    enableDegrade = false
    #disable
    disable = false
    #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
    max.commit.retry.timeout = "-1"
    max.rollback.retry.timeout = "-1"
    } ## transaction log store, only used in seata-server
    store {
    ## store mode: file、db
    mode = "db" ## file store property
    file {
    ## store location dir
    dir = "sessionStore"
    #degrade current not support
    enableDegrade = false
    #disable
    disable = false
    #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
    max.commit.retry.timeout = "-1"
    max.rollback.retry.timeout = "-1"
    } ## transaction log store, only used in seata-server
    store {
    ## store mode: file、db
    mode = "db" ## file store property
    file {
    ## store location dir
    dir = "sessionStore"
    } ## database store property
    db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
    datasource = "dbcp"
    ## mysql/oracle/h2/oceanbase etc.
    db-type = "mysql"
    driver-class-name = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://localhost:3306/seata"
    user = "wr"
    password = "wr"
    min-conn = 1
    max-conn = 3
    global.table = "global_table"
    branch.table = "branch_table"
    lock-table = "lock_table"
    query-limit = 100
    }
    }
  4. 编辑conf/regiester.conf

    registry {
    # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
    # 更改1
    type = "eureka" nacos {
    serverAddr = "localhost"
    namespace = ""
    cluster = "default"
    }
    eureka {
    # 更改2
    serviceUrl = "http://localhost:21001/eureka"
    application = "default"
    weight = "1"
    }
    redis {
    serverAddr = "localhost:6379"
    db = "0"
    }
    zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    }
    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 = "localhost"
    namespace = ""
    }
    consul {
    serverAddr = "127.0.0.1:8500"
    }
    apollo {
    app.id = "seata-server"
    apollo.meta = "http://192.168.1.204:8801"
    }
    zk {
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    }
    etcd3 {
    serverAddr = "http://localhost:2379"
    }
    file {
    name = "file.conf"
    }
    }

    本次实现,我们还没有添加configration的时候,因此只需要更改register块中的相关属性即可,在后续我们实现了nacos config之后,再同步更新这里。

  5. 启动服务端

    [root@localhost.localdomain /usr/local/geekplus/server/seata]# bin/seata-server.sh

SEATA 分布式事务入门DEMO-LMLPHP

eureka中看到如下8091端口的服务之后,即启动seata-server正常!

Client Configure

AT Model

需要在每一个业务库中添加数据表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=1 DEFAULT CHARSET=utf8;

Broadway-Demo

  • 第一步:加依赖

            <!--seata-->
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-seata</artifactId>
    <version>2.1.0.RELEASE</version>
    <exclusions>
    <exclusion>
    <artifactId>seata-all</artifactId>
    <groupId>io.seata</groupId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.0.0</version>
    </dependency>
  • 第二步:开启注解

    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

    在这里需要说明一下,我们需要排除掉SpringBoot默认自动注入的DataSourceAutoConfigurationBean, 因为SEATA是基于数据源拦截来实现的分布式事务,因此,我们需要自定义数据源配置信息:

    package com.geekplus.broadway.ws.tally.application;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import io.seata.rm.datasource.DataSourceProxy;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import javax.sql.DataSource; @Configuration
    public class DataSourceConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
    DruidDataSource druidDataSource = new DruidDataSource();
    return druidDataSource;
    } @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
    return new DataSourceProxy(druidDataSource);
    } @Bean
    public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(dataSourceProxy);
    sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
    .getResources("classpath*:/com/geekplus/*.xml"));
    sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
    return sqlSessionFactoryBean.getObject();
    }
    }

    该配置类,一般放在与启动类相同的目录即可!

  • 第三部:改配置

    spring:
    cloud:
    alibaba:
    seata:
    tx-service-group: sunrise_tx_group

以上三步是大多数SpringBoot 项目的通用做法,当然我们的SEATA暂时还不是那么完善,配置信息目前还不支持在application.yml中配置完全,因此,我们需要2个核心的client 配置文件file.confregister.conf.

  • file.conf 该文件主要是用于连接RM的,我们只需要关注上面所说的tx-service-group就行,其他配置默认就可以。

    transport {
    # tcp udt unix-domain-socket
    type = "TCP"
    #NIO NATIVE
    server = "NIO"
    #enable heartbeat
    heartbeat = true
    # the client batch send request enable
    enable-client-batch-send-request = true
    #thread factory for netty
    thread-factory {
    boss-thread-prefix = "NettyBoss"
    worker-thread-prefix = "NettyServerNIOWorker"
    server-executor-thread-prefix = "NettyServerBizHandler"
    share-boss-worker = false
    client-selector-thread-prefix = "NettyClientSelector"
    client-selector-thread-size = 1
    client-worker-thread-prefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    boss-thread-size = 1
    #auto default pin or 8
    worker-thread-size = 8
    }
    shutdown {
    # when destroy server, wait seconds
    wait = 3
    }
    serialization = "seata"
    compressor = "none"
    } service {
    #transaction service group mapping
    vgroup_mapping.sunrise_tx_group = "default"
    #only support when registry.type=file, please don't set multiple addresses
    default.grouplist = "127.0.0.1:8091"
    #disable seata
    disableGlobalTransaction = false
    } client {
    rm {
    async.commit.buffer.limit = 10000
    lock {
    retry.internal = 10
    retry.times = 30
    retry.policy.branch-rollback-on-conflict = true
    }
    report.retry.count = 5
    table.meta.check.enable = false
    report.success.enable = true
    }
    tm {
    commit.retry.count = 5
    rollback.retry.count = 5
    }
    undo {
    data.validation = true
    log.serialization = "jackson"
    log.table = "undo_log"
    }
    log {
    exceptionRate = 100
    }
    support {
    # auto proxy the DataSource bean
    spring.datasource.autoproxy = false
    }
    }
  • register.conf该文件是用于指定注册中心相关配置的,它有2个核心block

    • registry块

      此模板表明我们的注册中心使用类型,需要根据type设置来同步更新使用的配置信息,比如我们使用的eureka,因此我们更新eureka.serviceUrl="http://172.16.1.187:21001/eureka".

    • config 块

      该模块用来设置我们的配置中心相关配置(此处后续更新,我们会选择apollo

    registry {
    # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
    type = "eureka" nacos {
    serverAddr = "localhost"
    namespace = ""
    cluster = "default"
    }
    eureka {
    serviceUrl = "http://172.16.1.187:21001/eureka"
    application = "default"
    weight = "1"
    }
    redis {
    serverAddr = "localhost:6379"
    db = "0"
    }
    zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    }
    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 = "localhost"
    namespace = ""
    }
    consul {
    serverAddr = "127.0.0.1:8500"
    }
    apollo {
    app.id = "seata-server"
    apollo.meta = "http://192.168.1.204:8801"
    }
    zk {
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    }
    etcd3 {
    serverAddr = "http://localhost:2379"
    }
    file {
    name = "file.conf"
    }
    }
05-19 22:29