5. Spring Cloud: Seata distributed transactions

Table of contents

1. Introduction of Seata

Basic concepts of Seata

More principles and process analysis

2. The case of no distributed transaction control

3. Seata concept

Interpretation of the concept of business grouping

 5. Seata server installation and configuration

 6. Seata client (AT mode)

 Seven, Seata server adjustment configuration

Appendix A: Official scripts such as SQL required by Seata


1. Introduction of Seata

The full name of seata is: s implement extensiable  utonomoustransactionarchitecture , the Chinese literal translation is : simple, extensible, autonomous transaction architecture. 

As a cross-database distributed transaction management and solution, Seata provides four transaction mode solutions: AT, TCC, Saga, and XA. Among them, the AT mode has almost zero modification and zero intrusion to the business code. For related introduction, please refer to the official website.

  Seata is divided into a server (Seata Server) and a client (that is, each microservice). The server is the TC global coordination center, and the client is the TM and RM.

 Basic concepts of Seata

In Seata's architecture, there are three roles:

  • TC  (Transaction Coordinator) - Transaction Coordinator: maintains the state of global and branch transactions, and drives global transaction commit or rollback. (Personally, I feel that GTC is more intuitive if it is called "Global Transaction Coordinator")
  • TM  (Transaction Manager) - Transaction Manager: Define the scope of global transactions , start global transactions, commit or rollback global transactions.
  • RM  ( Resource Manager ) - Resource Manager: manages resources ( Resource ) of branch transactions , talks to TC to register branch transactions and report the status of branch transactions, and drives branch transaction commit or rollback.

 Among them, TC is a separately deployed Seata-Server server, TM and RM are Clients  embedded in each microservice application   .

In Seata, the life cycle diagram of a distributed transaction is as follows (the green arrow is the call link between services, and the global transaction xid is automatically transferred during the transfer process):

Note: The overall commit or rollback of the global transaction is determined by the initiator of the global transaction. After the initiator makes a decision, it informs the TC, and the TC notifies each service to perform the local commit/rollback operation of the branch transaction in each service.

 More principles and process analysis

See the article: [Graphic] Seata AT Mode Distributed Transaction Source Code Analysis_Old Time| YoungChen's Blog-CSDN Blog

2. The case of no distributed transaction control

   In the previous Java project ( 4. SpringCloud: Sentinel service flow control and service degradation_zyplanke's column-CSDN blog ) there are already payment services and order services. On the basis of its engineering, modify it (mainly increase access to the database)

 1. Add three dependencies of spring-boot-starter-data-jpa, mysql-connector-java, and druid-spring-boot-starter to pom.xml . The content is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.11</version>
        <relativePath/>
    </parent>

    <modules>
        <module>payment</module>
        <module>order</module>
    </modules>

    <groupId>com.example</groupId>
    <artifactId>myproject-global-pom</artifactId>
    <version>0.0.1-DEFAULT</version>
    <packaging>pom</packaging>
    <description>This is my project global pom config</description>
    <properties>
        <java.version>1.8</java.version>
        <springcloud.version>3.0.4</springcloud.version>
        <springcloudalibaba.version>2021.1</springcloudalibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${springcloudalibaba.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${springcloudalibaba.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>${springcloud.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>${springcloud.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>${springcloudalibaba.version}</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

 2. Payment service: define the payment service database table InnoDB engine (and insert a piece of data)

mysql> create schema payment;
mysql>  create table payment.T_PAY(order_id int, amount int, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY `PK_T_PAY` (order_id) ) ENGINE = InnoDB;
Query OK, 0 rows affected (0.02 sec)

mysql> desc payment.T_PAY;
+-------------+----------+------+-----+-------------------+-------------------+
| Field       | Type     | Null | Key | Default           | Extra             |
+-------------+----------+------+-----+-------------------+-------------------+
| order_id    | int      | YES  |     | NULL              |                   |
| amount      | int      | YES  |     | NULL              |                   |
| create_time | datetime | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+-------------+----------+------+-----+-------------------+-------------------+
3 rows in set (0.00 sec)

  3. Payment service: Modify the PaymentController.java of the payment service, the content is as follows (add database SQL, change the URL parameter to userid)

@RestController
public class PaymentController {
    @Value("${server.port}")
    private int myport;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    Logger logger = LoggerFactory.getLogger(PaymentController.class);

    @GetMapping("/dopay/{orderid}")
    public ResponseEntity<String> paylogic(@PathVariable("orderid") Long orderid) {
        int insert_rows = jdbcTemplate.update("insert into T_PAY (order_id, amount) values (" + orderid +", 999)");
        logger.info("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
        return ResponseEntity.ok("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
    }
}

 4. Payment service: Since this service uses Nacos as the configuration center, modify the configuration of Data ID=paymentService.properties in Nacos, and add the configuration of database connection information as follows:

5. Order service: define the order service database table (InnoDB engine)

mysql> create schema orders;
mysql> create table orders.T_Order (order_id int, address varchar(128), remark varchar(256), create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY `PK_T_Order` (order_id) ) ENGINE = InnoDB ;
Query OK, 0 rows affected (0.02 sec)

mysql> desc orders.T_Order;
+-------------+--------------+------+-----+-------------------+-------------------+
| Field       | Type         | Null | Key | Default           | Extra             |
+-------------+--------------+------+-----+-------------------+-------------------+
| order_id    | int          | YES  |     | NULL              |                   |
| address     | varchar(128) | YES  |     | NULL              |                   |
| remark      | varchar(256) | YES  |     | NULL              |                   |
| create_time | datetime     | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+-------------+--------------+------+-----+-------------------+-------------------+
4 rows in set (0.00 sec)

  6. Order service: Modify the OrderController.java of the order service. Call the payment service first, then simulate the exception. The content is as follows 

@RestController
public class OrderController {

    @Autowired
    private IPaymentServiceClient paymentServiceClient;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    Logger logger = LoggerFactory.getLogger(OrderController.class);
    boolean forcefail = true;

    @GetMapping("/consumer/{orderid}")
    public ResponseEntity<String> consumerFeign(@PathVariable("orderid") Long orderid) {
        String result = paymentServiceClient.dodopay(orderid).getBody(); // 调用支付服务进行支付
        logger.info("[paymentService result]: {}", result);

        jdbcTemplate.update("insert T_Order(order_id, address, remark) values (" + orderid + ", 'dizhi', '"+result+"')");

        //模拟在支付完成后,本订单事务后续处理过程中发生异常后,全局回滚功能
        if (forcefail) {
            throw new RuntimeException("模拟在支付完成后,本订单事务后续处理过程中发生异常!");
        }

        return ResponseEntity.ok ("调用订单服务完成。 订单orderid:" + orderid + ",   调用支付返回的Body:" + result);
    }
}

  6. Order service: Since this service uses Nacos as the configuration center, modify the configuration of Data ID=orderService.properties in Nacos, and add the configuration of database connection information as follows

 7. Test. curl http://localhost:8888/consumer/66

 8. Conclusion: In the process of paying first and then ordering into the warehouse, after the payment is completed, an exception occurs in the subsequent processing of the order transaction, which should have been returned as a whole. However, in fact, the records in the payment table still exist and have not been rolled back as a whole, failing to achieve cross-database transaction consistency.

Therefore, it is necessary to use distributed transaction components such as Seata to solve such problems.

3. Seata concept

Please read the official website documents first (required knowledge includes):

Interpretation of the concept of business grouping

Among them, most of the articles on the Internet are misleading about the transaction grouping and several related conceptual parameters. The correct understanding is:

tx-service-group transaction grouping

Transaction grouping is the resource logic concept of seata.

That is, transactions can be logically grouped according to the needs of microservices, and each group takes a name

Configured on the client side (microservice).

The form of configuration parameters in Spring is as follows:

seata.tx-service-group=mytest-tx-group

Or use spring.cloud.alibaba.seata.tx-service-group configuration

If not specified above, the default rule for the logical transaction group name is: spring.application.name value + "-seata-service-group"

vgroup-mapping

That is, the name of the cluster cluster composed of seata-server server nodes.

In the client (microservice), it is necessary to specify the vgroup-mapping used for the mapping (that is, the cluster on the server side) for each logical transaction group.

By adjusting this mapping relationship, you can switch to a different server cluster.

Configured on the client side (microservice).

Specify logical transaction grouping to be mapped to vgroup-mapping (the value of vgroup-mapping needs to be consistent with the cluster in registry.conf in seata-server).

The form of configuration parameters in Spring is as follows:

seata.service.vgroup-mapping.mytest-tx-group=beijing

Among them: red is the transaction group name

The value on the right side of the equal sign does not need quotation marks; it is the same as the cluster name of seata-server

grouplist

It is not the same level concept as above.

Its purpose is to directly configure the IP and port information of each seata-server server node for vgroup-mapping (that is, the server cluster) on the client.

Configured on the client side (microservice).

It is recommended to use seata.registry.type=nacos or other types (the microservice client and the seata-server server should be specified as nacos at the same time), because using Nacos, the client can automatically obtain the IP of the seata-server server node through Nacos and port information.

If it is not a registration center such as nacos, you need to directly specify the seata-server server node information through the following two parameters in the client (microservice) configuration:

The configuration parameters in Spring are as follows (officially not recommended):

seata.registry.type=file

seata.service.grouplist.beijing=seata-serverIP:Port

Among them: purple is the vgroup-mapping name (that is, the cluster name of seata-server)

Common errors in online articles are:

  1. These concepts on the Internet are unclear (in fact, it is mainly due to poorly written Seata official website documents, which are caused by plagiarism of many articles on the Internet without thinking);
  2. The mistaken understanding on the Internet is that the above three parameters still need to be configured on the seata-server server. In fact, these parameters are configured on the client side, not on the server side;
  3. The online error requires that the registry.conf and file.conf files need to be copied to the resources directory of the client (microservice), which is not required at all for SpringBoot applications.
  4. Others: The documents and examples on the official website are inconsistent with the latest seata version, and there are contradictions between documents. (For example, " -seata-service-group " above , the official website document is still wrongly written as " -fescar-service-group " in the <Transaction Grouping> chapter as of mid-December 2021.) PR is to fix some problems in the official document, which will be merged into the official document in late December 2021 and has been released to avoid continuing to mislead everyone.


4. Environmental introduction

  • Seata server seata-server: Deploying Seata Server and Seata needs to manage transaction-specific database MySQL
  • Seata client: each microservice. That is in this case include: payment service and order service.

 5. Seata server installation and configuration

1. Download and decompress seata-server

wget https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip
unzip seata-server-1.4.2.zip

After decompression, the directory result is:

├──bin
├──conf
├──log
└──lib

2. Configure seata-server. The configuration file can be seen in the conf directory of the Seata server:

  • registry.conf : This file must exist. Define what is needed for seata-server: registry registration center and config configuration center. in:
    • registry.type registry type optional range: file, nacos, eureka, redis, zk, consul, etcd3, sofa. Usually choose the nacos configuration center as the registration center.
    • config.type The configuration center type can be selected from: file, nacos, apollo, zk, consul, etcd3.
  • file.conf : This file.conf file is required only when you choose to configure registry.type=file or config.type=file in the server-side registry.conf file (the storage mode store of distributed transaction management can be specified in this file .mode)
  • Whether it is file, nacos, or other configuration sources. Both need to define the storage mode store.mode of distributed transaction management. There are three storage modes: file, db, redis.
    • If store.mode=file is selected, Seata's transaction-related information will be stored in memory and persisted to the local root.data file. The performance is relatively high. 
    • If you choose store.mode=db. Seata's transaction-related information is stored in a database. Using the database mode can support multiple seata-server startups to achieve high availability of seata-server.

For simplicity, this article will:

  • In the registry.conf file, set registry.type=nacos (and point the serverAddr in nacos to the Nacos server, and change the cluster to beijing); config.type=file.
  • Set store.mode=file in the file.conf file.

3. Start the seata-server server

./seata-server.sh -h 39.100.80.168 &

还可以加启动选项:
    --help 显示帮助
    -h: 本Seata服务向Nacos等注册时,以哪个IP信息作为Seata服务对外暴露IP(本选项不是指定本地侦听IP)。
        对于服务器是阿里云ESC等有NAT转换特别有用
    -p: The port to listen. Default: 8091
    -m: 服务端undo log store mode : file、db. Default: file
    -n: Server node,多个Server时,需区分各自节点,用于生成不同区间的transactionId,以免冲突
    -e: 多环境配置参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html

4. Check the registration result. Because registry.type=nacos is set in the registry.conf file. So you can see the registered service in Nacos.

Click to see the details, and pay attention to view the cluster information (the cluster name in the figure below comes from the cluster setting under registry.conf):

 6. Seata client (AT mode)

   1. Seata should be used, and dependencies should be added to the previous example project Maven. pom.xml is as follows:

<!-- 前面省略 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <version>${springcloudalibaba.version}</version>
        </dependency>
<!-- 后面省略 -->
  • The above passed spring-cloud-starter-alibaba-seata:2021.1 version, passed seata-spring-boot-starter:1.3.0, and the actual dependency is seata:1.3.0 version.
  • If the version of MySQL ≥ 8.0.23 is used, an error will be reported " isrduparser.JacksonUndoLogParser : json decode exception, Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value ( no delegate- or property-based Creator) ". Seata officially said that this problem has been fixed in 1.4.2, but the actual test found that Seata1.4.2 has not been fixed yet. Therefore, the MySQL database version can avoid this error because it is less than or equal to 8.0.22. See https://github.com/seata/seata/issues/3620# for details

Other:

  • The above dependency uses spring-cloud-starter-alibaba-seata instead of seata-spring-boot-starter. Because spring-cloud-starter-alibaba-seata has intercepted SeataHandlerInterceptor between services to transfer global transaction XID information when each service is called, it can be used directly, which is more convenient.
  • If the dependency is not to use seata-spring-boot-starter (or spring-cloud-starter-alibaba-seata), but to use seata-all directly, you need to write additional data source proxy code. Because seata-spring-boot-starter has implemented data source proxy and seata.enable-auto-data-source-proxy is true by default. For details, see the official "Seata Frequently Asked Questions No. 20" http://seata.io/zh-cn/docs/overview/faq.html

   2. In the local database of each microservice, ensure that the business tables participating in the distributed transaction have PK primary keys (otherwise Seata will report an error " Could not found any index in the table "). Seata currently only supports single-column primary keys and does not support composite primary keys. For details, see the official "Seata Frequently Asked Questions No. 13" http://seata.io/zh-cn/docs/overview/faq.html

   3. Due to the use of the Seata AT mode, it is necessary to create an undo_log table in the application database used by each microservice (this is not the database of the Seata server, but the business database of each microservice on the client side).

     For the source of the SQL statement script for creating tables, see Appendix A of this document. The AT mode is used here, taking MySQL as an example ( https://github.com/seata/seata/blob/develop/script/client/at/db/mysql.sql ) The databases used by the two services of payment and order are respectively Create the following table:

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

   Note: The table name `undo_log` can be modified. If you modify it, you need to modify the table creation SQL statement and the microservice configuration seata.client.undo.log-table= value at the same time

4. Configure Seata-related information in each microservice. Since the payment and order services themselves are managed by the Nacos configuration center, and the configuration content of the two services is the same, the following Seata-related configuration information is added to common commonshare.properties in the configuration center

#================Seata Client Config============
#是否启用Seata(默认启用)
seata.enabled=true

# 定义本服务的事务组(可以每个应用独立取名,也可以不同的应用使用相同的名字)
seata.tx-service-group=mytest-tx-group

# 指定逻辑事务组映射到vgroup-mapping(等号左侧为事务分组名,vgroup-mapping的值需要与seata-server中registry.conf中的cluster保持一致)
seata.service.vgroup-mapping.mytest-tx-group=beijing

seata.registry.type=nacos
seata.registry.nacos.server-addr=39.100.80.168:8848
seata.registry.nacos.application=seata-server
seata.registry.nacos.group=SEATA_GROUP

5. Add  the @GlobalTransactional  annotation to the entry of the entire business process that requires distributed transactions. Here the order order service is the entry point of the entire distributed transaction logic, so the annotation is added to OrderController.java, the content is as follows:

@RestController
public class OrderController {

    @Autowired
    private IPaymentServiceClient paymentServiceClient;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    Logger logger = LoggerFactory.getLogger(OrderController.class);

    boolean forcefail = true;

    @GetMapping("/consumer/{orderid}")
    @GlobalTransactional(timeoutMills = 28000, name = "gts-seata-example")
    public ResponseEntity<String> consumerFeign(@PathVariable("orderid") Long orderid) {
        logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
        String result = paymentServiceClient.dodopay(orderid).getBody(); // 调用支付服务进行支付
        logger.info("[paymentService result]: {}", result);

        jdbcTemplate.update("insert T_Order(order_id, address, remark) values (" + orderid + ", 'dizhi', '"+result+"')");

        //模拟在支付完成后,本订单事务后续处理过程中发生异常后,全局回滚功能
        if (forcefail) {
            throw new RuntimeException("模拟在支付完成后,本订单事务后续处理过程中发生异常!");
        }

        return ResponseEntity.ok ("调用订单服务完成。 订单orderid:" + orderid + ",   调用支付返回的Body:" + result);
    }
}

       Annotation options: timeoutMills is the timeout period, name is the name of the transaction, and  rollbackFor specifies which heterogeneous classes thrown by the function will be rolled back globally (if not specified, the default is RuntimeException). noRollbackFor specifies which heterogeneous classes thrown by the function will not be rolled back globally.

Note: The overall commit or rollback of the global transaction is determined by       the initiator of the global transaction (that is,  the service where @GlobalTransactional is located). That is to say, if the commt is applied globally, the initiator will notify the TC (seata-server), and then the TC will notify each branch to complete the local submission. If the global rollback is required, the initiator will notify the TC (seata-server), and the TC will notify each branch to complete the local rollback. 

         Therefore, in the service call link, the exception must be thrown to the initiator of the global transaction, so that it can be perceived by the @GlobalTransactional annotation of the initiator of the global transaction.

6. (Optional) In order to better observe the transmission of XID. Add log in PaymentController.java

@RestController
public class PaymentController {
    @Value("${server.port}")
    private int myport;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    Logger logger = LoggerFactory.getLogger(PaymentController.class);

    @GetMapping("/dopay/{orderid}")
    public ResponseEntity<String> paylogic(@PathVariable("orderid") Long orderid) {
        logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
        int insert_rows = jdbcTemplate.update("insert into T_PAY (order_id, amount) values (" + orderid +", 999)");
        logger.info("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
        return ResponseEntity.ok("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
    }
}

    7. Run the payment and order services respectively. test. curl http://localhost:8888/consumer/66   

          It can be found that the business databases of the two services either have data in effect at the same time, or have no data at the same time, achieving distributed transaction consistency.

 Seven, Seata server adjustment configuration

  The above uses config.type=file, store.mode=file in seata-server. Neither of these are suitable for a production environment. Therefore, adjustments are required: change config.type=file to Nacos configuration center, and store.mode=file to be stored in the database db.

   1. Obtain the SQL script for table creation in the Seata server database. For the source of the script, please refer to the instructions in Appendix A of this article (ie https://github.com/seata/seata/tree/develop/script/config-center )

 2. Execute the table creation SQL script. First create a schema named "seata" in the MySQL database. Then under the schema, execute the above SQL script (four tables: ` global_table` , ` branch_table` , ` lock_table` , ` distributed_lock` )

 3. Enter the conf directory under the server seata software installation directory, and edit the registry.conf file, as follows:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    application = "seata-server"
    serverAddr = "39.100.80.168:8848"
    group = "SEATA_GROUP"
    namespace = ""
    cluster = "beijing"
    username = ""
    password = ""
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "39.100.80.168:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = ""
    password = ""
    dataId = "seataServer.properties"
  }
}
  • Keep the service registry registry.type=nacos unchanged (that is, Seata continues to use the nacos registry, and the specific configuration of serverAddr, group, cluster, etc. under nacos depends on the actual situation).
  • Modify config.type=nacos (the specific serverAddr, group, dataId and other configurations under nacos are based on the actual situation)

  4. Obtain the configuration item content template of the configuration center. For the source of configuration content, please refer to the instructions in Appendix A of this article (ie https://github.com/seata/seata/tree/develop/script/config-center )

  5. Obtain the content of the "config.txt" file as a template reference (see: https://seata.io/zh-cn/docs/user/configurations.html for the meaning of each configuration item ).

       Because the "config.txt" file has a lot of original content, you need to choose from it (other configuration items do not need to display settings, just keep the default value). In addition, "config.txt" includes the configuration of the Seata server and the definition of the Seata client (that is, each microservice). Here, only the configuration related to the server and the more commonly used ones are selected. The modified configuration content is as follows:

#========= Seata Server Config:Server端连接数据库信息
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=Pwd_1234
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

   Manually copy the above content configuration to Nacos on the Nacos configuration center interface, as shown in the figure below. The dataId=seataServer.properties, group=SEATA_GROUP, etc. in the configuration center must be consistent with those defined in the registry.conf file . (Most online articles push the above content to Nacos through the shell script of nacos-config.sh. However, it is recommended to configure it manually, which is more convenient and the process is self-controllable)

 6. Restart the seata-server. ./seata-server.sh -h 39.100.80.168 &

 7. It can be found in the test that if the overall global transaction is successfully submitted or rolled back, no data will be left in the three tables of seata-server (the actual SQL action process is first insert, then update, and finally delete). Only unfinished global transactions will retain data in the three Tables.

Appendix A: Official scripts such as SQL required by Seata

see installation directoryseata/conf/README-zh.md. 该文件内如如下:

# 脚本说明

## [client](https://github.com/seata/seata/tree/develop/script/client) 

> 存放用于客户端的配置和SQL

- at: AT模式下的 `undo_log` 建表语句
- conf: 客户端的配置文件
- saga: SAGA 模式下所需表的建表语句
- spring: SpringBoot 应用支持的配置文件

## [server](https://github.com/seata/seata/tree/develop/script/server)

> 存放server侧所需SQL和部署脚本

- db: server 侧的保存模式为 `db` 时所需表的建表语句
- docker-compose: server 侧通过 docker-compose 部署的脚本
- helm: server 侧通过 Helm 部署的脚本
- kubernetes: server 侧通过 Kubernetes 部署的脚本

## [config-center](https://github.com/seata/seata/tree/develop/script/config-center)

> 用于存放各种配置中心配置项模板和脚本,执行时都会读取 `config.txt`配置文件,并写入配置中心

- nacos: 用于向 Nacos 中添加配置
- zk: 用于向 Zookeeper 中添加配置,脚本依赖 Zookeeper 的相关脚本,需要手动下载;ZooKeeper相关的配置可以写在 `zk-params.txt` 中,也可以在执行的时候输入
- apollo: 向 Apollo 中添加配置,Apollo 的地址端口等可以写在 `apollo-params.txt`,也可以在执行的时候输入
- etcd3: 用于向 Etcd3 中添加配置
- consul: 用于向 consul 中添加配置

Guess you like

Origin blog.csdn.net/zyplanke/article/details/121216853