官方文档地址
1、Seata service下载地址:https://github.com/seata/seata/releases
2、下载完之后解压。
3、conf目录下自定义配置
seata—>conf—>file.conf
## transaction log store, only used in seata-server
store {
## store mode: file、db
##改成db
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) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
## 如果要是没有seata数据库,要建立一个
url = "jdbc:mysql://172.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8"
user = "123"
password = "123"
minConn = 5
maxConn = 30
## 建好数据库之后新建下面的这三张表
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
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;
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(6),
`gmt_modified` DATETIME(6),
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
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;
seata—>conf—>registry.conf 这里用的是nacos
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server-chenmf"
serverAddr = "172.0.0.1:8848"
namespace = "ffa677cd-a2e5-4af6-bf32-102fc1397d33"
cluster = "default"
username = ""
password = ""
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "172.0.0.1:8848"
namespace = "ffa677cd-a2e5-4af6-bf32-102fc1397d33"
group = "DEFAULT_GROUP"
username = ""
password = ""
}
}
4、进入seata-server解压之后的bin文件夹,双击seata-server.bat启动。
5、配置、导包(每个微服务都要加)
# 这里配置的是微服务之间的调用超时时间
feign:
client:
config:
default:
connect-timeout: 4000
read-timeout: 4000
# Seata 配置项,对应 SeataProperties 类
seata:
application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name}
tx-service-group: seata-crm-group # Seata 事务组编号,用于 TC 集群名,此处的名称一定要与 vgroup-mapping下配置的参数保持一致
# Seata 服务配置项,对应 ServiceProperties 类
service:
# 虚拟组和分组的映射
vgroup_mapping:
seata-crm-group: default
# Seata 注册中心配置项,对应 RegistryProperties 类
registry:
type: nacos # 注册中心类型,默认为 file
nacos:
cluster: DEFAULT_GROUP # 使用的 Seata 分组
namespace: ffa677cd-a2e5-4af6-bf32-102fc1397d33 # Nacos 命名空间
serverAddr: 172.0.0.1:8848 # Nacos 服务地址
application: seata-server-chenmf
com.alibaba.cloud
spring-cloud-alibaba-seata
2.2.0.RELEASE
seata-spring-boot-starter
io.seata
io.seata
seata-spring-boot-starter
1.2.0
6、在每个微服务下面建立一张undo_log表
CREATE TABLE IF NOT EXISTS `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'increment id',
`branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(100) 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 NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME NOT NULL COMMENT 'modify datetime',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
7、在微服务业务上加入@GlobalTransactional注解
A服务调B服务saveUser()方法并插入数据
@GlobalTransactional(rollbackFor = Exception.class)
@PostMapping(value = "saveclient")
public Integer save(@RequestBody User user){
User one = new User();
one.setId(4432);
testTransactionService.saveUser(one);
// 手动抛出异常
int a = 1/0;
userService.save(user);
return user.getId();
}
8、测试,通过微服务A调用微服务B中的saveUser()事务方法,执行完毕,返回微服务A之后,手动抛出异常,看B事务是否已经回滚
9、在B执行完毕之后,返回微服务A,抛出异常之前debug,查看库里的user表和undo_log表里面数据的变化