一、Seata的介绍
Seata是分布式事务的解决方案,根据2PC协议来实现。由TC事务协调器、TM事务管理器、RM资源管理器组成,其中TC可以实现集群部署,能够避免2PC中的事务管理器的单点故障问题。Seata提供了AT、XT、TCC、Saga四种模式,其中AT是其首推模式。
分布式事务的使用场景
使用场景:一个应用跨数据库调用时,需要保证对不同数据库操作的事务; 不同服务之间的调用(涉及到不同数据库的修改); 当对分库分表的数据进行操作场景
2PC 两阶段提交协议
在介绍2PC协议之前,先来了解下TM和RM的含义,TM是指事务管理器来管理不同事物的状态,通知各RM提交或者回滚。
RM资源管理器:就是具体事务的执行者。
两阶段提交顾名思义就是分为两个阶段提交事务,第一阶段:TM通知各RM准备提交事务,各RM收到通知后进行数据的修改以及日志的记录,并且将事务的状态修改为可以交,并将事务的状态提交给TM。
阶段二:TM根据各RM返回的事务状态,判断事务提交还是回滚。如果所有的RM返回可以提交事务,TM就会通知各RM提交事务,只要有一个RM返回失败,TM就会通知各RM回滚事务。
我们订单服务下订单的过程为例展示2PC的过程,分为创建订单和扣减库存2步
2PC 存在的问题
1.同步阻塞:在第二阶段确定提交或回滚前都创建订单和减少库存的操作,都会一直锁定着资源
2.单点故障: TM如果宕机的话,处于第二阶段的RM会一直处于阻塞状态
3.数据不一致:如果有一部分RM没有收到提交的信息,一部分RM收到了提交的信息,就会产生数据不一致的问题
AT模式
AT模式依赖于关系型数据库事务的实现,就是说分支事务由本地事务支持,然后通过TC事务协调器来判断各分支事务的执行情况,最终决定回滚或者提交。是对前面提到的2PC的优化增强,在RM执行完第一阶段会释放本子资源和数据连接。
TCC模式
TCC模式相对于AT模式而言,就是手动的事务处理,prepare、commit/cancel执行的应用程序自定义的逻辑,是一种侵入式的编码方式,但是好处就是各RM不需要依赖关系型数据库的自身的事务来完成全局的事务,而是可以跨应用、跨数据库来实现。
XA模式
XA模式与AT模式相似,区别在于XA在第一阶段不会释放连接,而是等到第二阶段提交或者回滚后。
从编程模式看也是相似的,不同点在于XA和AT的代理实现机制不同,且XA不需要undo日志回滚表。
二、Seata的搭建使用
以AT模式为例的搭建步骤:
1.准备注册中心/配置中心,这里使用的是nacos,用来TC和各RM之间服务的发现
2.TC事务协调器需要单独启动,并配置注册中心/配置中心、数据库的信息
3.应用程序各RM配置seata的注册中心、配置中心信息
4.创建数据库表,seata相应的数据表(全局事务表、全局锁信息等)、各RM的中undo表以及测试业务相关表
- seata配置文件的存储模式改为db
store.mode=db
store.lock.mode=file
store.session.mode=file
store.db.url=jdbc:mysql://localhost:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root
2.应用服务seata注册中心和配置中心的配置
seata:
application-id: ${spring.application.name}
#注意事务分组的名称要与配置中心的相同
tx-service-group: default_tx_group
registry:
# 指定nacos作为注册中心
type: nacos
nacos:
application: seata-server
server-addr: localhost:8848
namespace:
group: SEATA_GROUP
config:
# 指定nacos作为配置中心
type: nacos
nacos:
server-addr: localhost:8848
namespace: seata
group: SEATA_GROUP
data-id: seataServer.properties
3.启动TC以及应用服务,启动后可以在注册中心查看
4.调用测试