分布式基础
CAP理论(一致性、可用性、分区容错性)
2PC协议
两段式协议:数据库准备阶段和数据库提交(都成功就会去提交),mysql和oracle都支持
XA方案解决分布式事务
- 在准备阶段执行实际的业务操作,不提交事务,==但资源锁定==
- 提交阶段,只要有一个失败事务管理器就会回滚所有操作,提交阶段结束后资源锁才会被释放
XA的问题: - 数据库需要支持XA协议
- 必须等提交完后资源锁才会被释放,性能较差
Seata解决分布式事务
概念:分支事务让他提交,由事务管理器判断分支事务是否成功,有一个失败,就把已经成功添加的数据删除,不占用资源锁,且代码0侵入,也是属于2PC方案,不过需要单独启用seata事务协调服务,但是==不支持dubbo和springcloud==
seata执行流程
- 需要在事务数据库中加入undo_log表(这个表记录事务前后执行sql和反执行sql)
- 在事务开启方加入@GlobalTransactional注解(全局事务),然后会向事务管理器注册并得到事务全局id(XID)
- 发起者和被调用方都要加入@Transactional注解
- 发起者提交分支事务,调用feign并携带XID
- 被调用服务向事务管理器注册事务得到分支事务id,上报分支事务提交情况
- 成功删除undo_log记录,否则解析undo_log执行反向sql
分布式事务解决方案值TCC
三阶段:
- try阶段(业务检查及资源预留)
- confirm阶段是确认提交
- cancel阶段,回滚取消分支业务,只要Try成功,Confirm一定成功。若Confirm阶段出错了,需引入重试机制或人工处理
- TM事务管理器,TM在发起全局事务时生成全局事务记录,全局事务ID贯穿整个分布式事务调用链条,用来记录事务上下文, 追踪和记录状态,由于Confirm 和cancel失败需进行重试,因此需要实现为幂等,幂等性是指同一个操作无论请求 多少次,其结果都相同。
TCC需要注意的三种异常处理:空回滚、幂等、悬挂
Hmily实现TCC事务
- 创建hmily数据库
- 创建事务控制表,每个数据库都创建rry、confirm、cancel日志表,记录try、confirm、cancel执行记录
- 事务发起方
- try方法
- 通过Hmily获取全局事务id HmilyTransactionContextLocal.getInstance().get().getTransId();
- try幂等校验
- try悬挂处理
- 业务
- confirm:空
- cancel
- cancel幂等校验
- 业务反执行
- try方法
- 事务被调方
- try方法
空 - confirm:
- 通过Hmily获取全局事务id
- confirm幂等校验
- 正式增加金额
- cancel
空
- try方法
分布式事务解决方案值可靠消息最终一致性
RocketMQ方案
- 生产者执行完业务后发送事务消息,这条信息是被标记预备状态,不可以被消费
- MQ Server回应发送消息成功
- 生产者执行本地事务
- 生产者本地事务成功后会发送commit消息,MQ Server会将消息标记为可消费状态,本地事务执行失败会向MQ Server发送rallback消息,将删除消息
- 事务回查:如果本地事务执行超时、宕机,MQ Server会不听询问同组的其他生产者来获取事务状态,MQ Server根据回查结果决定是否投递消息
- 消费者接收到消息会执行本地事务并提交,如果消费失败则会重复消费,因此需要消费前实现幂等控制
总结:Rocket不会要求强一致性,只要最终结果一致就可以,适用于事务被调方什么时候执行都可以的场景,和seata与Hmily不一样,seat与aHmily都要求强一致性与