Five minute experience of distributed transaction framework Seata

seata is an open source distributed transaction solution dedicated to providing high-performance and easy-to-use distributed transaction services. seata will provide users with AT, TCC, SAGA and XA transaction modes, and build a one-stop distributed solution for users. The purpose of this tutorial is to provide a quick start to the case of seata. Please refer to the official cases and documents for details.

Seata server building

In Seata, the transaction manager is a separate service, which can be used out of the box without secondary development. Download address . In this case, we use version 2.1.0. After downloading and decompressing, you need to configure the Seata server. You need to configure the file.conf and registry.conf .

among file.conf It is to configure the data storage mode of Seata server and support local documents and databases. This paper uses local file storage directly. The configuration is as follows:

## transaction log store, only used in seata-server
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://"
    user = "mysql"
    password = "mysql"
    minConn = 5
    maxConn = 30
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000

registry.conf It is to configure the registry of Seata server. This case is registered on eureka.

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

  nacos {
    application = "seata-server"
    serverAddr = "localhost"
    namespace = ""
    cluster = "default"
    username = ""
    password = ""
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"

Business code initialization

go Official website To download the code, you can also go to the case sorted out in this article. Download address:

Project introduction

After downloading, the file directory of the project project is as follows. There are 5 projects in total, including eureka (Registration Center), business (transaction service), storage (inventory service), order (order service) and account (account service). Seata server and other four business services need to be registered with eureka. sql directory is the script to initialize sql. The directory structure of the project is as follows.

├── account
├── bussiness
├── eureka
├── order
├── pom.xml
├── sql
└── storage

Initialize sql

Create the database of seata in the database, and import the database script under the sql directory.

Configuration changes

After introducing the sdk of seata into the business code, you need to configure file.conf and registry.conf , see the code in the source code. stay Configure mysql connection in:

Start up works

Start Seata server, euraka, business, storage, order, account project in turn. Address to visit eureka: http://localhost:8761 /, you can see that all services are registered with eureka.

When you start the business service, the following data is inserted into the database:

    public void initData() {
        jdbcTemplate.update("delete from account_tbl");
        jdbcTemplate.update("delete from order_tbl");
        jdbcTemplate.update("delete from storage_tbl");
        jdbcTemplate.update("insert into account_tbl(user_id,money) values('U100000','10000') ");
        jdbcTemplate.update("insert into storage_tbl(commodity_code,count) values('C100000','200') ");


seata official has written the code logic, just test it directly.


The logic of this interface code is as follows:

 @RequestMapping(value = "/purchase/commit", produces = "application/json")
    public String purchaseCommit() {
        try {
            businessService.purchase("U100000", "C100000", 30);
        } catch (Exception exx) {
            return exx.getMessage();
        return "Global transaction commit";

That is, buy 30 stocks. The current stock and amount are enough, so the transaction is normal.

After completion, you can see the account in the database_ The money with id 1 of TBL will be reduced by 5, order_ A new record will be added in TBL, storage_ The count field with id 1 of TBL is reduced by 1

2020-05-21 16:09:12.388 INFO [AsyncCommitting_1]io.seata.server.coordinator.DefaultCore.doGlobalCommit:240 -Committing global transaction is successfully done, xid =

Abnormal transaction rollback occurred

Call the following interface:


The logic of this interface code is as follows:

    public String purchaseRollback() {
        try {
            businessService.purchase("U100000", "C100000", 99999);
        } catch (Exception exx) {
            return exx.getMessage();
        return "Global transaction commit";

The sub interface first deducts the inventory, then deducts the money, finally queries the database, finds that the inventory of the database is negative, throws an exception, and rolls back. After the completion, the data in the database does not change, and the rollback is successful. It can be seen that the distributed transaction rollback operation succeeded.

reference material

Keywords: Database MySQL SQL Spring

Added by Cogen on Thu, 25 Jun 2020 07:25:46 +0300