【知识积累】阿里分布式事务解决方案Seata实战

tech2022-11-01  121

一、准备

官网 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 );

 

最新回复(0)