指事务的操作位于不同的节点上,需要保证事务的 AICD 特性。例如:你下单,要走订单服务和库存服务,如何确保事务的正确执行
如何解决
理论依据
AICD:
事务具有4个特征,原子性,一致性,隔离性,持久性原子性:要么都执行,要么都不执行一致性:事务不能不一部分执行成功,一部分执行不成功,导致数据不一致隔离性:一个事务要操作的数据,不要被另一个事务同时操作持久性:一旦事务提交,那将永久修改数据库的数据
CAP:
c:一致性:所有节点存入数据,返回响应a:高可用:某个节点存入数据,返回响应p:分区容错性:某一个节点挂了,还可以有其他节点可以使用
BASE
BA:基本可用:出现错误,还可以对外提供服务s:软状态:中间状态e:数据一致性,中间状态存在有时间期限,一道期限,必须保证数据一致性
技术
2pc(二阶段提交)
之一阶段:让每个参与者执行sql,如果都执行成功,则到第二阶段提交,如不成功,进行回滚第二阶段:进行commit操作(这一部分无法解决commit时,有服务出现错误的情况)
缺点:
commit的时候发生 故障(某一服务没有commit),导致数据不一致在等待所有参与者响应时,所有的参与者都是阻塞状态TCC(两阶段补偿提交)
重点:3个 (try,确认,补偿),字段新增了一个中间状态和一个预留字段(用于存减了多少库存,或者减去/加上某某值)
例子:我们买了2件衣服
物品id
物品名称
库存
状态
预留字段
1
衣服
20
未更新
首先我们先调用try ,作用:看库存够不够,把这一行数据的状态改为更新中,再预留字段中存入我们要减的库存
物品id
物品名称
库存
状态
预留字段
1
衣服
20
更新中
2
更新状态就不能被其他操作然后执行sql,commit,如果都成功了,调用确认 ,进行状态的更新,预留字段的值变为0
物品id
物品名称
库存
状态
预留字段
1
衣服
18
已更新
如果有一个没有执行成功,那么就会调用补偿 ,进行状态的更新,预留字段的值变为0
物品id
物品名称
库存
状态
预留字段
1
衣服
20
已取消
rabbitmq
重点:
保证生产者能将消息传到mq(消息确认机制)mq能够正常地被生产者消费(消息确认机制,重试机制)不能被重复消费(将消息id放到redis中)最终实现数据最终一致