Seata implements distributed transaction control

Table of contents

1. Start Seata

1.1 download seata

1.2 Modify the configuration file and initialize

2. Use Seata to implement transaction control

2.1 Initialize the data table

2.2 Add configuration


1. Start Seata

1.1 download seata

Download address: https://github.com/seata/seata/releases/v1.3.0/  

1.2 Modify the configuration file and initialize

Decompress the downloaded seata (non-source package) compressed package and enter the conf directory  

Modify file.conf ​​​​​​( non-source package)

 

Create the database Seata and initialize the data table  (source package)

Unzip the seata-1.4.0 source package, and enter the seata-1.4.0\script\server\db directory, copy and run the mysql.sql script to complete the seata server database initialization.  

 

Modify registry.conf (non-source package)  

 Decompress the downloaded seata (non-source package) compressed package and enter the conf directory

 

 Modify the config.txt configuration in the script/config-center directory in seata-1.4.0 (source package):

 

Initialize Seata configuration into Nacos  (non-source package)

Right-click in the seata-1.4.0\script\config-center\nacos directory and select git bash here to run the git command window. and enter the following command:sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -u nacos -w nacos

 

After the execution is successful, you can open the Nacos console. In the configuration list, you can see that many configurations with Group SEATA_GROUP initialized.  

 

Start the seata service (non-source package)

Directly enter the seata\bin directory of the seata service, double-click to run the seata-server.bat file. Or use the following command to run:

cd bin
seata-server.bat -p 9000 -m file
seata-server.bat -h ip地址 -p 9000 -m file 

 

2. Use Seata to implement transaction control

2.1 Initialize the data table

Enter the source package seata-1.4.0\script\client\at\db directory, copy and run the mysql.sql database script to complete the creation of the undo_log table, which is the table used by Seata to record transaction logs.  

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;

2.2 Add configuration

  • add dependencies  

Introduce the following dependencies in zmall-order and zmall-product modules respectively:  

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<!-- 如果已经添加了nacos配置中心依赖,则可以不加入 -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  •  DataSourceProxyConfig

Seata implements transaction branching through the proxy data source, so it is necessary to configure the Bean of io.seata.rm.datasource.DataSourceProxy, which is the default data source of @Primary, otherwise the transaction will not be rolled back and distributed transactions cannot be realized. Please add the DruidDataSource configuration class in zmall-order , as follows:

package com.zking.zmall.config;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.xa.DataSourceProxyXA;
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 javax.sql.DataSource;

@Configuration
public class DataSourceProxyConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Primary
    @Bean("dataSourceProxy")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        //AT模式
        return new DataSourceProxy(druidDataSource);
        //XA模式
        //return new DataSourceProxyXA(druidDataSource);
    }
}
  •  Exclude the DataSource data source auto-configuration class on the startup class
@EnableFeignClients
@EnableDiscoveryClient
@MapperScan({"com.zking.zmall.mapper"})
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ZmallOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZmallOrderApplication.class, args);
    }
}

Perform the following configurations in microservices that require distributed transactions:

  • application.yml  
spring:
  datasource:
    #type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/zmall?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    username: root
    password: 1234


  •  registry.conf

Add the seata configuration file registry.conf in the resources directory of the microservice module, which comes from the configuration file in the seata-server/conf directory.  

registry {
    type = "nacos"
    nacos {
        serverAddr = "localhost"
        namespace = "public"
        cluster = "default"
    }
}
config {
    type = "nacos"
    nacos {
        serverAddr = "localhost"
        namespace = "public"
        cluster = "default"
    }
}
  •  bootstrap.yaml
spring:
  application:
    name: service-product
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 # nacos的服务端地址
        namespace: public
        group: SEATA_GROUP
    alibaba:
      seata:
        tx-service-group: my_test_tx_group
  •  Start a global transaction in the order microservice
@GlobalTransactional  //seata全局事务控制
@Transactional
@Override
public Order createOrder(Integer pid, Integer num) {
    //根据商品ID修改商品对应的库存
    productService.updateStock(pid,num);
    //模拟程序执行报错
    int i=1 / 0;
    //新增订单
    Order order=new Order();
    //此处只是做模拟操作
    this.save(order);
    return order;
}

Guess you like

Origin blog.csdn.net/m0_63300795/article/details/128337718