官网:
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
事务类型共有4中,分别为AT/TCC/SAGA/XA
AT模式(推荐):
- 基于支持本地 ACID 事务的关系型数据库。
- Java 应用,通过 JDBC 访问数据库。
自动模式,只支持关系型数据库,如:mysql,sql server,不支持非关系型数据库,如:redis,需要undo_log表支持
参考:https://seata.io/zh-cn/docs/dev/mode/at-mode.html
TCC模式(不推荐,工作量太大):
自己编写提交以及回滚的语句,一个业务实现逻辑,需要写3个方法.绑定为1组,分别为prepare(准备),commit(提交),rollback(回滚),
当所有方法prepare都执行正常时,TC会调用commit方法,否则会调用rollback
参考:https://seata.io/zh-cn/docs/dev/mode/tcc-mode.html
SAGA模式:
此模式的思想是对应每个业务逻辑层编写一个新的类,然后指定业务逻辑层方法发生异常时,运行新编写的类中的代码
一般用于修改已写好的类(老项目升级为微服务)
参考:https://seata.io/zh-cn/docs/user/saga.html
XA模式:
- 支持XA 事务的数据库。
- Java 应用,通过 JDBC 访问数据库。
支持XA协议的数据库的分布式事务,使用比较少
参考:https://seata.io/zh-cn/docs/dev/mode/xa-mode.html
XA | ATT | TCC | SAGA | |
---|---|---|---|---|
一致性 | 强一致 | 弱一致 | 弱一致 | 最终一致 |
隔离性 | 完全隔离 | 基于全局锁隔离 | 基于资源预留隔离 | 无隔离 |
代码侵入 | 无 | 无 | 要编写3个接口 | 要编写状态机和补偿业务 |
性能 | 差 | 好 | 非常好 | 非常好 |
场景 | 对一致性、隔离性有高要求的业务 | 基于关系型数据库的大多数分布式事务场景都可以 | 对性能要求较高的事务。有非关系型数据库要参与的事务。 | 业务流程长、业务流程多参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口 |
项目一般使用AT模式去解决事务问题
AT模式运行过程
1.事务的发起方™会向事务协调器(TC)申请一个全局事务id,并保存
2.Seata会管理事务中所有相关的参与方的数据源,将数据操作之前和之后的镜像都保存在undo_log表中,这个表是seata组件规定的表,没有它就不能实现效果,依靠它来实现提交(commit)或回滚(roll back)的操作
3.事务的发起方™会连同全局id一起通过远程调用运行资源管理器(RM)中的方法
4.RM接收到全局id,去运行指定方法,并将运行结果的状态发送给TC
5.如果所有分支运行都正常,事务管理器™会通过事务协调器通知所有模块执行数据库操作,真正影响数据库内容,反之如果有任何一个分支模块运行异常,都会通知TC,再由TC通知所有分支将数据库操作回滚,恢复成运行之前的样子
使用Seata分布式事务的AT模式,则该项目的数据库中,必须包含undo_log表,建表SQL语句如下:
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8mb3;
需要下载Seata服务端程序,并运行bin目录下的seata-server.bat
运行前,必须在PATH环境变量内添加jdk的bin目录,如: C:\Program Files\Java\jdk1.8.0_271\bin
seata-server.bat -h 127.0.0.1 -m file
出现 如下信息表示启动成功,端口默认为8091
SLF4J: A number (18) of logging calls during the initialization phase have been intercepted and are
SLF4J: now being replayed. These are subject to the filtering rules of the underlying logging system.
SLF4J: See also http://www.slf4j.org/codes.html#replay
17:47:24.869 INFO --- [ main] io.seata.config.FileConfiguration : The file name of the operation is registry
17:47:24.872 INFO --- [ main] io.seata.config.FileConfiguration : The configuration file used is D:\seata-server-1.4.2\conf\registry.conf
17:47:24.918 INFO --- [ main] io.seata.config.FileConfiguration : The file name of the operation is file.conf
17:47:24.918 INFO --- [ main] io.seata.config.FileConfiguration : The configuration file used is D:\seata-server-1.4.2\conf\file.conf
....................中间省略一堆....................
17:47:25.373 INFO --- [ main] i.s.core.rpc.netty.NettyServerBootstrap : Server started, listen port: 8091
Seata依赖
<!-- Seata和SpringBoot整合依赖 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<!-- Seata 完成分布式事务的两个相关依赖(Seata会自动使用其中的资源) -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
配置项
seata:
data-source-proxy-mode: AT #使用AT模式(可以不加,默认就是)
tx-service-group: csmall_group #定义分组名称,为了与其他项目区分
service:
vgroup-mapping:
csmall_group: default #这个分组的事务使用Seata的默认配置完成
grouplist:
default: localhost:8091 #配置Seata默认的地址和端口号
注意同一个事务,必须在同一个在tx-service-group中,并且指定了相同的Seata地址与端口,此处为grouplist.default
AT模式下,添加完依赖与配置后,使用Seata非常简单,只需要在起点业务(触发者/TM)的逻辑方法上,
添加专用的注解(@GlobalTransactional)即可!
达内:lzy