seata的相关信息量认识沉淀
seata作为一个分布式任务
我们作为开发者,应该从哪些认识seata掌握那些信息量
我提供一个认识框架
1.如何搭建配置到微服务生态里
2.在代码里,应该如何使用
3.提供了哪些机制,供使用
4.seata的实现原理是什么
5.在项目中,使用,需要注意什么。
你提出的"搭建与配置->代码使用->机制->原理->注意事项"这个框架很完整,这也是掌握Seata最高效的路径。当前主流的Seata版本(如1.5.x到2.x)在Spring Cloud/Alibaba生态中应用广泛。
下面就按这5个维度为你梳理。
1. 如何搭建与配置
将Seata纳入微服务生态,核心是部署TC(事务协调者),再将客户端(你的微服务)集成进来。
- 环境准备:首先,你需要从Seata官网下载
seata-server。由于TC需要记录事务状态,建议使用MySQL作为其数据源,为此需要创建global_table、branch_table和lock_table三张表。 - 部署TC服务:
- 配置:修改
application.yml,将store.mode设为db并配置好数据库连接。 - 注册与配置中心:为了让微服务能发现TC,通常将TC注册到Nacos上;同时,TC集群的复杂配置可以也放到Nacos配置中心统一管理,实现动态生效。
- 高可用部署:高可用很简单,只需启动多个TC实例并注册到Nacos即构成集群。通过修改Nacos中
service.vgroupMapping.<你的事务组名>的值,可以无侵入地动态切换所有微服务连接的TC集群。
- 配置:修改
- 微服务集成:在每个需要参与分布式事务的微服务中:
- 加依赖:引入
seata-spring-boot-starter。 - 配代理:Seata AT模式需要代理数据源,通常是配置一个
DataSourceProxy的Bean。 - 设映射:在
application.yml中指定tx-service-group(事务分组),Seata客户端会根据Nacos中的映射关系找到你的TC集群。
- 加依赖:引入
2. 在代码里如何使用
对开发者而言,Seata的使用方式非常"低侵入",主要体现在注解的使用上。
- 发起全局事务:在整个分布式事务的起点方法上,添加
@GlobalTransactional注解即可,它类似于单体应用中的@Transactional。 - 编写分支事务:在各个参与者(如库存服务、账户服务)的方法上,只需添加标准的
@Transactional注解即可。Seata会自动通过全局事务ID(XID)的传递,将这些本地事务纳入同一个全局事务的管理中。
3. 提供了哪些核心机制
Seata提供了四种"事务模式",你可以把它们理解为处理数据一致性的四种策略。
- AT模式(Automatic Transaction):无侵入的自动模式,也是Seata的默认模式。它通过解析SQL自动生成回滚SQL(基于
undo_log表)。性能较好,适合绝大多数微服务场景,是入门首选。 - TCC模式(Try-Confirm-Cancel):高性能的手动模式,需要你实现
Try(预留资源)、Confirm(确认提交)、Cancel(补偿回滚)三个接口。该模式不依赖于数据库,性能最强,但有代码侵入,适合对一致性要求极高的金融核心场景。 - XA模式:强一致的数据库级协议,直接利用数据库的XA协议实现两阶段提交。能保证强一致性且无代码侵入,但性能最差,适合对一致性要求极高且并发不高的老旧系统。
- SAGA模式:长事务的补偿模式,通过状态机或注解编排一系列子事务,每个子事务都配有补偿操作。适合处理业务流程长、环节多的场景,但开发和管理复杂度较高。
4. 实现原理:以AT模式为例
理解了AT模式的工作原理,就掌握了Seata的核心精髓。
- 角色划分:整个架构由TC(事务协调者)、TM(事务管理器)和RM(资源管理器)三部分构成。
- TM:在发起方(@GlobalTransactional)开始工作,向TC申请开启一个全局事务,TC返回一个全局唯一ID,即XID。
- RM:在参与者(@Transactional)工作,它负责执行本地事务,并向TC注册分支事务。
- TC:作为大脑,它维护着全局事务和所有分支事务的状态,并最终决定是全局提交还是全局回滚。
- 两阶段提交过程:
- 一阶段:RM执行业务SQL,并在提交前记录数据修改前后的快照到
undo_log表,然后立即提交本地事务,释放数据库锁。同时,它会获取一个全局锁,防止其他全局事务修改同一行数据。 - 二阶段:如果TM收到所有分支成功的报告,会通知TC进行全局提交,TC随后通知所有RM异步删除
undo_log即可,非常轻量。如果任一分支失败,TC会通知所有RM执行回滚,RM会根据undo_log中的"前镜像"生成反向SQL来恢复数据,实现最终一致。
- 一阶段:RM执行业务SQL,并在提交前记录数据修改前后的快照到
5. 项目中使用的注意事项
在实际项目中,有几个"坑"和最佳实践值得特别留意。
- 全局事务ID传递:最常见的问题就是XID丢失,导致分支事务无法加入全局事务。务必确保你的远程调用(如Feign、Dubbo)的拦截器能自动传递XID。
- AT模式的脏写问题:高并发下,一个Seata分布式事务在二阶段回滚前,若被另一个未受Seata管理的本地事务修改了数据,就会造成脏写。应对策略是配置全局锁的重试等待机制,或在SQL中使用
select for update等悲观锁进行强制隔离。 - 事务超时与性能:全局事务不宜处理耗时很长的业务。建议为
@GlobalTransactional设置一个合理的timeoutMills。对于非核心的主流程(如发送短信、记录日志),应将其剥离出分布式事务,通过本地事务加消息队列异步处理。 - TCC模式的幂等性与空回滚:实现TCC模式时,Confirm和Cancel接口可能因为网络重试而被调用多次,因此必须保证幂等性。同时,也要预防空回滚,即在Try方法从未被执行的情况下,收到了Cancel请求,此时应直接返回成功。
undo_log表管理:AT模式下,undo_log表会不断增长。建议设置定期清理任务,比如保留7天的数据,避免其成为数据库负担。
