分布式事务

使用场景

例如: 电商下单 订单生成+扣减库存
订单生成属于订单系统,扣减库存属于库存系统

db本地事务如何保证的?

redo、undo、ACID
AD(日志文件)、CI锁 详见MySql学习笔记//TODO

刚性事务acid&柔性事务base

刚性事务:强一致性(ACID)
柔性事务:基本可用,最终一致性(BASE理论)


BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写。BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。接下来看一下BASE中的三要素:
1、基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性----注意,这绝不等价于系统不可用。比如:
(1)响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒
(2)系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面
2、软状态
软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时
3、最终一致性
最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

XA协议

  • 事务管理器(TM)Transaction Manager
  • 资源管理器(RM)Resource Manager

2PC两阶段提交

  • 流程
image.png
  • 缺点

1.TM单点问题,挂了,整个2PC彻底完蛋
2.执行过程是完全同步的。各参与者在等待其他参与者响应的过程中都处于阻塞状态,高并发性能问题
3.仍然存在不一致风险。如果由于网络异常等意外导致只有部分参与者收到了commit请求,就会造成部分参与者提交了事务而其他参与者未提交的情况。

3PC

1.基于2PC,在预备之前,加入询问阶段,用于判断网络是否通畅(询问不锁定资源)
2.增加超时机制(TM/RM都有):
(TM超时默认失败)
(第三阶段)RM超时默认提交

3PC也不能完全保证一致性,只是降低了数据不一致的概率.降低了资源锁定概率

解决方案

  • 本地事件表+mq方案
image.png
  • LCN

lock 锁定事务单元
confirm 确认事务单元
notify 通知事务单元

  • Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案

  • TCC
  • 原理介绍:
    TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务Confirm:确认执行业务Cancel: 取消执行业务
  • 模式特点:
    该模式对代码的嵌入性高,要求每个业务需要写三种步骤的操作。
    该模式对有无本地事务控制都可以支持使用面广。
    数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
  • 不适用于全数据库,纯手工流程过于复杂,用于redis月mysql同步事务还可.数据库LCN更加合适
    private static Map maps = new HashMap<>();

    @Transactional(rollbackFor = Exception.class)
    @TccTransaction
    public String tryX(@RequestBody XBean bean){
        //数据库操作
        //do SQL
       //maps中记录唯一标识id
        maps.put("a",id);
        return "try成功";
    }
    public String confirmX(XBean bean){
        System.out.println("pay confirm");
        return "confirm成功";
    }
    public String cancelX(XBean bean){
        //从map获取id,供取消使用
        Integer a = maps.get("a");
        //do SQL 取消tryX()方法操作
        return "取消支付成功";
    }
  • 可靠性消息最终一致性
image.png
  • 最大努力通知

一般适用于三方服务,例如支付宝/微信的支付回调,如果消费方不应答,由高到底降低频率通知固定次数后将不在通知,提供查询接口供消费方调用

  • 事务消息
image.png

你可能感兴趣的:(分布式事务)