Table of contents
2. Use the default configuration to build a stand-alone Seata Server
3. Stand-alone Seata Server, database storage transaction log
1. Modify the conf/file.conf file and change it to db
4. Seata Server cluster mode construction
1. Modify file.conf under the conf folderEdit
2. Modify the registry.conf file under the conf folder
5. Use seata (AT mode) in the project
4. Configure the data source proxy
6. Add annotations to the methods that need to add distributed transactions
1. Download and decompress
Download address: Releases seata/seata GitHub
2. Use the default configuration to build a stand-alone Seata Server
1. Start command
nohup sh bin/seata-server.sh -h 127.0.0.1 -p 8091 -m file &
2. Parameter introduction
3. Stand-alone Seata Server, database storage transaction log
1. Modify the conf/file.conf file and change it to db
2. Import database script
CREATE DATABASE /*!32312 IF NOT EXISTS*/`seata` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */;
USE `seata`;
/*Table structure for table `branch_table` */
DROP TABLE IF EXISTS `branch_table`;
CREATE TABLE `branch_table` (
`branch_id` bigint(20) NOT NULL,
`xid` varchar(128) NOT NULL,
`transaction_id` bigint(20) DEFAULT NULL,
`resource_group_id` varchar(32) DEFAULT NULL,
`resource_id` varchar(256) DEFAULT NULL,
`branch_type` varchar(8) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
`client_id` varchar(64) DEFAULT NULL,
`application_data` varchar(2000) DEFAULT NULL,
`gmt_create` datetime(6) DEFAULT NULL,
`gmt_modified` datetime(6) DEFAULT NULL,
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `branch_table` */
/*Table structure for table `global_table` */
DROP TABLE IF EXISTS `global_table`;
CREATE TABLE `global_table` (
`xid` varchar(128) NOT NULL,
`transaction_id` bigint(20) DEFAULT NULL,
`status` tinyint(4) NOT NULL,
`application_id` varchar(32) DEFAULT NULL,
`transaction_service_group` varchar(32) DEFAULT NULL,
`transaction_name` varchar(128) DEFAULT NULL,
`timeout` int(11) DEFAULT NULL,
`begin_time` bigint(20) DEFAULT NULL,
`application_data` varchar(2000) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`xid`),
KEY `idx_gmt_modified_status` (`gmt_modified`,`status`),
KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `global_table` */
/*Table structure for table `lock_table` */
DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table` (
`row_key` varchar(128) NOT NULL,
`xid` varchar(96) DEFAULT NULL,
`transaction_id` bigint(20) DEFAULT NULL,
`branch_id` bigint(20) NOT NULL,
`resource_id` varchar(256) DEFAULT NULL,
`table_name` varchar(32) DEFAULT NULL,
`pk` varchar(36) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`row_key`),
KEY `idx_branch_id` (`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. Start command
nohup sh bin/seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 &
4. Parameter introduction
4. Seata Server cluster mode construction
1. Modify file.conf under the conf folder
2. Modify the registry.conf file under the conf folder
3. Start the seata cluster
nohup sh bin/seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 &
nohup sh bin/seata-server.sh -h 127.0.0.1 -p 8092 -m db -n 2 &
nohup sh bin/seata-server.sh -h 127.0.0.1 -p 8093 -m db -n 3 &
4. View on nacos
5. Use seata (AT mode) in the project
1. Introduce seata dependency
<!-- seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<!-- 注册 Seata 数据源需要连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<optional>true</optional>
</dependency>
2. Create the undo.log table
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;
3. Configure transaction grouping (write file.conf and registry.conf files in the resources directory)
3.1, file.conf file
## transaction log store, only used in seata-server
store {
## store mode: file、db、redis
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 = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false"
#数据库账户和密码
user = ""
password = ""
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
}
}
# 配置事务分组为 imooc-ecommerce default为集群的名称
service {
vgroupMapping.imooc-ecommerce = "default"
default.grouplist = "127.0.0.1:8091"
}
client {
async.commit.buffer.limit = 10000
lock {
retry.internal = 10
retry.times = 30
}
}
3.2, registry.conf file
registry {
# file、nacos、eureka、redis、zk、consul
type = "file"
file {
name = "file.conf"
}
}
config {
type = "file"
file {
name = "file.conf"
}
}
4. Configure the data source proxy
package com.imooc.ecommerce.conf;
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* <h1>Seata 所需要的数据源代理配置类</h1>
* */
@Configuration
public class DataSourceProxyAutoConfiguration {
private final DataSourceProperties dataSourceProperties;
public DataSourceProxyAutoConfiguration(DataSourceProperties dataSourceProperties) {
this.dataSourceProperties = dataSourceProperties;
}
/**
* <h2>配置数据源代理, 用于 Seata 全局事务回滚</h2>
* before image + after image -> undo_log
* */
@Primary
@Bean("dataSource")
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(dataSourceProperties.getUrl());
dataSource.setUsername(dataSourceProperties.getUsername());
dataSource.setPassword(dataSourceProperties.getPassword());
dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
return new DataSourceProxy(dataSource);
}
}
5. Load the interceptor SeataHandlerInterceptor to realize the transfer of xid between microservices.
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* <h2>添加拦截器配置</h2>
* */
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// 添加用户身份统一登录拦截的拦截器
registry.addInterceptor(new LoginUserInfoInterceptor())
.addPathPatterns("/**").order(0);
// Seata 传递 xid 事务 id 给其他的微服务
// 只有这样, 其他的服务才会写 undo_log, 才能够实现回滚
registry.addInterceptor(new SeataHandlerInterceptor()).addPathPatterns("/**");
}
/**
* <h2>让 MVC 加载 Swagger 的静态资源</h2>
* */
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").
addResourceLocations("classpath:/static/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
}
6. Add annotations to the methods that need to add distributed transactions
@GlobalTransactional(rollbackFor = Exception.class)