一、准备
官网 https://seata.io/zh-cn/docs/overview/what-is-seata.html本文采用AT模式 https://seata.io/zh-cn/docs/dev/mode/at-mode.htmlseata-server版本 1.3MySql 版本 5.6.41项目源码 https://gitee.com/mycode2018/spring-cloud-2020/tree/master/alibaba-seata
二、下载seata-server
https://seata.io/zh-cn/docs/user/quickstart.html
步骤 4: 启动服务
从 https://github.com/seata/seata/releases,下载服务器软件包,将其解压缩。
三、修改配置文件
seata\conf\file.conf
service {
#transaction service group mapping
#修改,fbs_tx_group随便起名字
vgroup_mapping.fbs_tx_group = "default"
#only support when registry.type=file, please don't set multiple addresses
# seata server的地址
default.grouplist = "127.0.0.1:8091"
#disable seata
disableGlobalTransaction = false
}
## 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.cj.jdbc.Driver"
#数据库地址
url = "jdbc:mysql://127.0.0.1:3306/seata-server?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"
#数据库账号
user = "root"
#数据库密码
password = "1234"
minConn = 5
maxConn = 30
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
queryLimit = 100
}
}
seata\conf\registry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
#注册中心的指定
type = "eureka"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
#eureka的配置 注册地址和微服务保持一致,不要忘记账号和密码
eureka {
serviceUrl = "http://root:1234@localhost:8761/eureka/"
#注册到eureka的名称
application = "seata-server"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
#配置的方式
type = "file"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = ""
password = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
appId = "seata-server"
apolloMeta = "http://192.168.1.204:8801"
namespace = "application"
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
etcd3 {
serverAddr = "http://localhost:2379"
}
#指向上面的file.conf文件
file {
name = "file.conf"
}
}
四、启动seata-server
\seata\bin\seata-server.bat
访问:http://localhost:8761/
五、在seata-server库下创建全局事务表、分支事务表、全局锁表
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`) USING BTREE,
KEY `idx_gmt_modified_status` (`gmt_modified`,`status`) USING BTREE,
KEY `idx_transaction_id` (`transaction_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='全局事务表';
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 DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
PRIMARY KEY (`branch_id`) USING BTREE,
KEY `idx_xid` (`xid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='分支事务表';
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`) USING BTREE,
KEY `idx_branch_id` (`branch_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='全局锁';
六、每个业务数据库下创建回滚日志表
1、seata-rm-one
DROP TABLE IF EXISTS `tbl_one`;
CREATE TABLE `tbl_one` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;
DROP TABLE IF EXISTS `undo_log`;
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`) USING BTREE,
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
2、seata-rm-two
DROP TABLE IF EXISTS `tbl_two`;
CREATE TABLE `tbl_two` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4;
DROP TABLE IF EXISTS `undo_log`;
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`) USING BTREE,
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
3、seata-rm-three
DROP TABLE IF EXISTS `tbl_three`;
CREATE TABLE `tbl_three` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
DROP TABLE IF EXISTS `undo_log`;
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`) USING BTREE,
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
七、每个微服务resources目录下添加file.conf和registry.conf文件
service {
#transaction service group mapping
vgroup_mapping.fbs_tx_group= "default"
#only support when registry.type=file, please don't set multiple addresses
default.grouplist = "127.0.0.1:8091"
#disable seata
disableGlobalTransaction = false
}
client {
rm {
async.commit.buffer.limit = 10000
lock {
retry.internal = 10
retry.times = 30
retry.policy.branch-rollback-on-conflict = true
}
report.retry.count = 5
table.meta.check.enable = false
report.success.enable = true
}
tm {
commit.retry.count = 5
rollback.retry.count = 5
}
undo {
data.validation = true
log.serialization = "jackson"
log.table = "undo_log"
}
log {
exceptionRate = 100
}
support {
# auto proxy the DataSource bean
spring.datasource.autoproxy = false
}
}
## transaction log store, only used in seata-server
store {
## store mode: file、db
mode = "db"
## file store property
file {
## store location dir
dir = "sessionStore"
}
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
datasource = "druid"
## mysql/oracle/h2/oceanbase etc.
db-type = "mysql"
driver-class-name = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata-server?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"
user = "root"
password = "1234"
}
}
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "eureka"
nacos {
serverAddr = "localhost"
namespace = ""
cluster = "default"
}
eureka {
serviceUrl = "http://root:root@localhost:8761/eureka/"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = "0"
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
serverAddr = "localhost"
namespace = ""
}
consul {
serverAddr = "127.0.0.1:8500"
}
apollo {
app.id = "seata-server"
apollo.meta = "http://192.168.1.204:8801"
}
zk {
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
八、每个微服务添加Maven依赖
<!-- alibaba-seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
九、application.yml配置
spring:
application:
name: seata-one
cloud:
alibaba:
seata:
#和seata server的file.conf(vgroup_mapping.fbs_tx_group= "default")以及每个微服务resources目录下的file.conf(vgroup_mapping.fbs_tx_group= "default")要一致
tx-service-group: fbs_tx_group
十、访问的方法添加注解@GlobalTransactional(rollbackFor = Exception.class)
1、alibaba-seata-rm-one
package com.darren.center.seata.one.controller;
import com.darren.center.seata.one.service.RmOneService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <h3>spring-cloud-2020</h3>
* <p></p>
*
* @author : Darren
* @date : 2020年09月02日 20:56:03
**/
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RmOneService rmOneService;
/**
* 注册中心 http://localhost:8761/
*
* http://192.168.229.1:8001/test/rm1
* @return
*/
@GlobalTransactional(rollbackFor = Exception.class)
@GetMapping("/rm1")
public String rm1(){
rmOneService.rm1();
return "rm1 success";
}
/**
* http://192.168.229.1:8001/test/rm1-update
* @return
*/
@GlobalTransactional(rollbackFor = Exception.class)
@GetMapping("/rm1-update")
public String rm1Update(){
rmOneService.rm2Update();
return "rm1 update success";
}
}
package com.darren.center.seata.one.service;
import com.darren.center.seata.one.dao.OneDao;
import com.darren.center.seata.one.entity.One;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class RmOneService {
@Autowired
private OneDao oneDao;
@Autowired
private RestTemplate restTemplate;
public String rm1(){
rm2();
rm3();
One rm1 = new One(1, "rm1");
oneDao.insertSelective(rm1);
//异常测试,发生异常时,rm1发生异常时,所有的数据是否回滚
//int i = 1/0;
return "";
}
public String rm2Update(){
//rm2 更新
rm2UpdateRemote();
One rm1 = new One(1, "rm1");
oneDao.insertSelective(rm1);
//异常测试,发生异常时,rm1发生异常时,所有的数据是否回滚
//int i = 1/0;
return "";
}
/**
* 调用seata 2 插入一条新数据
*/
private void rm2() {
restTemplate.getForEntity("http://seata-two/test/rm2", null);
}
/**
* 调用seata 2 更新数据
*/
private void rm2UpdateRemote() {
restTemplate.getForEntity("http://seata-two/test/rm2-update", null);
}
/**
* 调用seata 3
*/
private void rm3() {
restTemplate.getForEntity("http://seata-three/test/rm3", null);
}
}
2、alibaba-seata-rm-two
package com.darren.center.seata.two.controller;
import com.darren.center.seata.two.service.RmTwoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <h3>spring-cloud-2020</h3>
* <p></p>
*
* @author : Darren
* @date : 2020年09月02日 20:52:41
**/
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RmTwoService rmTwoService;
@GetMapping("/rm2")
public String rm2(){
rmTwoService.rm2();
return "rm2 success";
}
@GetMapping("/rm2-update")
public String rm2Update(){
rmTwoService.rm2Update();
return "rm2 update success";
}
}
package com.darren.center.seata.two.service;
import com.darren.center.seata.two.dao.TwoDao;
import com.darren.center.seata.two.entity.Two;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Random;
/**
* <h3>spring-cloud-2020</h3>
* <p></p>
*
* @author : Darren
* @date : 2020年09月02日 21:06:00
**/
@Service
public class RmTwoService {
@Autowired
private TwoDao twoDao;
public String rm2(){
Two rm2 = new Two(1, "rm2");
twoDao.insertSelective(rm2);
//异常测试,发生异常时,rm2发生异常时,所有的数据是否回滚
//int i = 1/0;
return "";
}
public String rm2Update(){
List<Two> lists = twoDao.selectAll();
Two two = lists.get(0);
two.setName(two.getName() + new Random().nextInt(100));
twoDao.updateByPrimaryKeySelective(two);
//异常测试,发生异常时,rm2发生异常时,所有的数据是否回滚
//int i = 1/0;
return "";
}
}
3、alibaba-seata-rm-three
package com.darren.center.seata.three.controller;
import com.darren.center.seata.three.service.RmThreeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <h3>spring-cloud-2020</h3>
* <p></p>
*
* @author : Darren
* @date : 2020年09月02日 21:09:04
**/
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RmThreeService rmThreeService;
@RequestMapping("/rm3")
public String rm3(){
rmThreeService.rm3();
return "rm3 success";
}
}
package com.darren.center.seata.three.service;
import com.darren.center.seata.three.dao.ThreeDao;
import com.darren.center.seata.three.entity.Three;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <h3>spring-cloud-2020</h3>
* <p></p>
*
* @author : Darren
* @date : 2020年09月02日 20:09:38
**/
@Service
public class RmThreeService {
@Autowired
private ThreeDao threeDao;
public String rm3(){
Three rm3 = new Three(1, "rm3");
threeDao.insertSelective(rm3);
return "";
}
}
十一、启动项目
十二、测试点
1、rm1、rm2、rm3插入完成,rm1发生异常,那么数据是否会回滚
2、rm2更新完成,rm1插入完成,rm1发生异常,那么数据是否会回滚
3、rm2更新完成,seata-server宕机,然后重启seata-server,那么数据是否会回滚
十三、观察全局事务表、分支事务表、全局锁表、回滚日志表的数据
#全局事务表
INSERT INTO `seata-server`.`global_table` (
`xid`,
#全局事务ID
`transaction_id`,
#全局事务ID
`status`,
#状态
`application_id`,
#事务管理器ID
`transaction_service_group`,
#事务组
`transaction_name`,
#事务名称 - 方法名
`timeout`,
#超时时间 60S
`begin_time`,
#开始时间
`application_data`,
#应用数据
`gmt_create`,
#创建时间
`gmt_modified` #修改时间
)
VALUES
(
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
'1',
'seata-one',
'fbs_tx_group',
'rm1()',
'60000',
'1599100092006',
NULL,
'2020-09-03 10:28:12',
'2020-09-03 10:28:12'
);
#分支事务表1
INSERT INTO `seata-server`.`branch_table` (
`branch_id`,
#分支ID
`xid`,
#全局事务ID
`transaction_id`,
#全局事务ID
`resource_group_id`,
#数据源组ID
`resource_id`,
#数据源ID
`branch_type`,
#分支类型 AT
`status`,
#状态
`client_id`,
#客户端ID
`application_data`,
#应用数据
`gmt_create`,
#创建时间
`gmt_modified` #修改时间
)
VALUES
(
'44731838966534145',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
NULL,
'jdbc:mysql://localhost:3306/seata-rm-one',
'AT',
'2',
'seata-one:127.0.0.1:12784',
NULL,
'2020-09-03 10:28:22',
'2020-09-03 10:28:22'
);
#分支事务表2
INSERT INTO `seata-server`.`branch_table` (
`branch_id`,
#分支ID
`xid`,
#全局事务ID
`transaction_id`,
#全局事务ID
`resource_group_id`,
#数据源组ID
`resource_id`,
#数据源ID
`branch_type`,
#分支类型 AT
`status`,
#状态
`client_id`,
#客户端ID
`application_data`,
#应用数据
`gmt_create`,
#创建时间
`gmt_modified` #修改时间
)
VALUES
(
'44731816451510273',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
NULL,
'jdbc:mysql://localhost:3306/seata-rm-two',
'AT',
'2',
'seata-two:127.0.0.1:12643',
NULL,
'2020-09-03 10:28:16',
'2020-09-03 10:28:16'
);
#分支事务表3
INSERT INTO `seata-server`.`branch_table` (
`branch_id`,
#分支ID
`xid`,
#全局事务ID
`transaction_id`,
#全局事务ID
`resource_group_id`,
#数据源组ID
`resource_id`,
#数据源ID
`branch_type`,
#分支类型 AT
`status`,
#状态
`client_id`,
#客户端ID
`application_data`,
#应用数据
`gmt_create`,
#创建时间
`gmt_modified` #修改时间
)
VALUES
(
'44731819240722432',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
NULL,
'jdbc:mysql://localhost:3306/seata-rm-three',
'AT',
'2',
'seata-three:127.0.0.1:13366',
NULL,
'2020-09-03 10:28:17',
'2020-09-03 10:28:17'
);
#全局锁1
INSERT INTO `seata-server`.`lock_table` (
`row_key`,
`xid`,
#全局事务ID
`transaction_id`,
#全局事务ID
`branch_id`,
#分支ID
`resource_id`,
#数据源ID
`table_name`,
#数据表
`pk`,
`gmt_create`,
#创建时间
`gmt_modified` #修改时间
)
VALUES
(
'jdbc:mysql://localhost:3306/seata-rm-one^^^tbl_one^^^3',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
'44731838966534145',
'jdbc:mysql://localhost:3306/seata-rm-one',
'tbl_one',
'3',
'2020-09-03 10:28:21',
'2020-09-03 10:28:21'
);
#全局锁2
INSERT INTO `seata-server`.`lock_table` (
`row_key`,
`xid`,
`transaction_id`,
`branch_id`,
`resource_id`,
`table_name`,
`pk`,
`gmt_create`,
`gmt_modified`
)
VALUES
(
'jdbc:mysql://localhost:3306/seata-rm-three^^^tbl_three^^^4',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
'44731819240722432',
'jdbc:mysql://localhost:3306/seata-rm-three',
'tbl_three',
'4',
'2020-09-03 10:28:16',
'2020-09-03 10:28:16'
);
#全局锁3
INSERT INTO `seata-server`.`lock_table` (
`row_key`,
`xid`,
`transaction_id`,
`branch_id`,
`resource_id`,
`table_name`,
`pk`,
`gmt_create`,
`gmt_modified`
)
VALUES
(
'jdbc:mysql://localhost:3306/seata-rm-two^^^tbl_two^^^6',
'192.168.244.1:8091:44731799200337920',
'44731799200337920',
'44731816451510273',
'jdbc:mysql://localhost:3306/seata-rm-two',
'tbl_two',
'6',
'2020-09-03 10:28:16',
'2020-09-03 10:28:16'
);
#回滚表,记录在每个业务数据库
INSERT INTO `seata-rm-one`.`undo_log` (
`id`,
`branch_id`,
#分支事务ID
`xid`,
#全局事务ID
`context`,
`rollback_info`,
#回滚信息 记录前置镜像和后置镜像
`log_status`,
#回滚日志状态
`log_created`,
#回滚日志创建时间
`log_modified`,
#回滚日志修改时间
`ext`
)
VALUES
(
'3',
'44731838966534145',
'192.168.244.1:8091:44731799200337920',
'serializer=jackson',
'{\"@class\":\"io.seata.rm.datasource.undo.BranchUndoLog\",\"xid\":\"192.168.244.1:8091:44731799200337920\",\"branchId\":44731838966534145,\"sqlUndoLogs\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.undo.SQLUndoLog\",\"sqlType\":\"INSERT\",\"tableName\":\"tbl_one\",\"beforeImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords\",\"tableName\":\"tbl_one\",\"rows\":[\"java.util.ArrayList\",[]]},\"afterImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords\",\"tableName\":\"tbl_one\",\"rows\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Row\",\"fields\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"id\",\"keyType\":\"PrimaryKey\",\"type\":4,\"value\":3},{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"name\",\"keyType\":\"NULL\",\"type\":12,\"value\":\"rm1\"}]]}]]}}]]}',
'0',
'2020-09-03 10:28:21',
'2020-09-03 10:28:21',
NULL
);
INSERT INTO `seata-rm-two`.`undo_log` (
`id`,
`branch_id`,
#分支事务ID
`xid`,
#全局事务ID
`context`,
`rollback_info`,
#回滚信息 记录前置镜像和后置镜像
`log_status`,
#回滚日志状态
`log_created`,
#回滚日志创建时间
`log_modified`,
#回滚日志修改时间
`ext`
)
VALUES
(
'7',
'44731816451510273',
'192.168.244.1:8091:44731799200337920',
'serializer=jackson',
'{\"@class\":\"io.seata.rm.datasource.undo.BranchUndoLog\",\"xid\":\"192.168.244.1:8091:44731799200337920\",\"branchId\":44731816451510273,\"sqlUndoLogs\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.undo.SQLUndoLog\",\"sqlType\":\"INSERT\",\"tableName\":\"tbl_two\",\"beforeImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords\",\"tableName\":\"tbl_two\",\"rows\":[\"java.util.ArrayList\",[]]},\"afterImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords\",\"tableName\":\"tbl_two\",\"rows\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Row\",\"fields\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"id\",\"keyType\":\"PrimaryKey\",\"type\":4,\"value\":6},{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"name\",\"keyType\":\"NULL\",\"type\":12,\"value\":\"rm2\"}]]}]]}}]]}',
'0',
'2020-09-03 10:28:16',
'2020-09-03 10:28:16',
NULL
);
INSERT INTO `seata-rm-three`.`undo_log` (
`id`,
`branch_id`,
#分支事务ID
`xid`,
#全局事务ID
`context`,
`rollback_info`,
#回滚信息 记录前置镜像和后置镜像
`log_status`,
#回滚日志状态
`log_created`,
#回滚日志创建时间
`log_modified`,
#回滚日志修改时间
`ext`
)
VALUES
(
'3',
'44731819240722432',
'192.168.244.1:8091:44731799200337920',
'serializer=jackson',
'{\"@class\":\"io.seata.rm.datasource.undo.BranchUndoLog\",\"xid\":\"192.168.244.1:8091:44731799200337920\",\"branchId\":44731819240722432,\"sqlUndoLogs\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.undo.SQLUndoLog\",\"sqlType\":\"INSERT\",\"tableName\":\"tbl_three\",\"beforeImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords\",\"tableName\":\"tbl_three\",\"rows\":[\"java.util.ArrayList\",[]]},\"afterImage\":{\"@class\":\"io.seata.rm.datasource.sql.struct.TableRecords\",\"tableName\":\"tbl_three\",\"rows\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Row\",\"fields\":[\"java.util.ArrayList\",[{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"id\",\"keyType\":\"PrimaryKey\",\"type\":4,\"value\":4},{\"@class\":\"io.seata.rm.datasource.sql.struct.Field\",\"name\":\"name\",\"keyType\":\"NULL\",\"type\":12,\"value\":\"rm3\"}]]}]]}}]]}',
'0',
'2020-09-03 10:28:16',
'2020-09-03 10:28:16',
NULL
);