Seata
seata就是一个分布式系统跨服务调用,保证分布式系统的一致性。
比如有三个服务现在: 订单服务 - 账号服务 - 库存服务
分布式系统指标 CAP
Consistency 一致性(数据一致性)
Available 可用性 (访问任何的健康节点,必须能得到反馈,而不是超时和拒绝)
Partition tolerance 分区容错性(系统能够在遇到网络分区(例如,节点之间的通信发生故障,导致部分节点之间无法通信,如A B可以通信 但是B和C不行)的情况下继续运行)
在分布式系统无法满足CAP三个属性,只能任意满足2个
Base对CAP的解决思路思路
Basically available(基本可用) 在分布式系统出现故障,同意损失部分可用性。
比如一个节点在一个集群出现了故障,我们可以把它从这个节点剔除,一旦他恢复了可用,就把他加入到我们集中中继续可用。
Soft state(软状态):在一定时间,允许出现中间状态,比如临时的不一致性状态。
数据只会临时不一致,给我一些时间,我会处理
Eventually consistent(最终一致性):虽然无法保证一致性,但是可以保证最终数据一致性
我保证最终的结果是一致性。
因此得出解决方案 借鉴CAP和BASE
AP model:各个子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据就行了(或者撤销),实现最终一致。
CP model: 各个子事务执行完别提交,相互等待,都执行完了同时提交 or 同时回滚(有人失败了),最终达成强一致性但事务等待的过程,处于弱可用状态(锁定资源,无法访问)。
Seate study
三个角色
TC transaction coorinator 事务协调者
维护全局和分支事务的状态,协调事务提交或者回滚
TM transaction 事务管理器
定义事务的范围,开始全局事务、提交回滚全局事务。
RM Resource Manager 资源管理者
管理分支处理资源(数据库),与TC交谈以注册分支事务和报告分支事务的状态,并驱动事务的提交或者回滚
比如一个分布式事务 (TM)他的调用范围是A B C,就是管理范围,当A服务接口方法被执行(TM会代理接口方法),TM会拦着这个方法去TC发起请求全局事务。等我们RM都提交完了,我们的TM就会检查我们的事务状态,判断是让TC提交还是回滚
解决方案
**业务入侵:**它意味着技术方案的实施需要对业务层的代码进行修改或增加额外的逻辑,从而使得业务逻辑变得复杂,难以维护。
XA model 强一致性分阶段事务,系统了可用性,无业务侵入
我们TC向我们RM发送一个消息,告诉他们你们可以准备执行了,然后RM都去执行自己的业务,但是不要提交把执行的结果告诉我们的TM,然后TM决定是全部提交还是全部取消。
seate:
adta-source-proxy-mode: XA
然后在在事务入口添加@GlobalTransactional
@GlobalTransactional
public Long create(Long id){
//创建订单
mapper.insert(id);
//扣除
//减少库存
}
XA是强一致性会锁定资源,强一致性,通过数据库事务机制回滚
AT model: 最终一致的分阶段事务模式,无业务侵入,也就是seata的默认模式
TM首先会向我们TC申请全局事务,然后我们的TM告诉我RM,你可以执行了, 然后我们的RM执行完毕会立刻提交数据给数据库,但是这里出现了一个问题,我都提交了我怎么回滚?
所以at解决方案就是就是记录更新前后的数据快照(undolog).然后TM来判断是否提交还是回滚,然后删除以前更新前后快照版本
所以AT不会一致占用资源,效率会比XA快。
AT看重最终一致性,通过快照来回滚,不锁定资源
适用于:对一致性、隔离性有高要求的业务
AT模式脏写问题
也就是我事务会直接提交可能会脏写,AT的解决方案就是加了一个全局锁实现读写隔离。
但是还有一个极端情况会出现脏写。我们在修改字段的时候,seata没有管理的事务他也来修改这个字段了,他也没有获取全局锁。解决的方案就是在业务上避免不同的事务操作同一个字段。如果真的出现了就把事务交给seata管理
全局锁
seata的全局锁并不是数据库的而是逻辑层的,他的作用就是在逻辑层面管理资源的锁定防止并发事务对同一事务操作
seate:
adta-source-proxy-mode: XA
适用于关系型数据库,大多数分布式事务场景都可以。
TCC model 最终一致的分阶段事务模式,有业务侵入
其实TCC和AT很像,唯一不同的就是需要人工编码实现数据恢复,如果想要人工恢复需要实现3个方法。
Try:资源的检测和预留 资源的操作
confirm:完成资源的业务操作 提交
cancel:预留资源的释放
TCC的优点就是,直接提交事务,释放数据库资源,性能好
相比AT不生成快照,不适用全局锁,性能好
不依赖数据库事务,是依赖补偿的操作,比如我在try增加了,那么我在cancel直接补偿回来就好了,比如适用非事务数据库redis
confirm和cancel可能会失败,失败了seata会重试,做好幂等处理。
对性能要求高,非关系形数据库。
SAGA model: 长事务模式,有业务侵入
他就是直接提交本地事务,如果失败了就写补偿业务回滚
适合业务流程比较多,业务比较长的情况。
Seate的使用
首先搭建TC服务并且注册到注册中心,然后在微服务集成seate