美文网首页
分布式事务解决方案

分布式事务解决方案

作者: sunpy | 来源:发表于2022-08-05 20:58 被阅读0次

本地事务


什么是本地事务?
本地事务是解决单个数据源上的数据操作的一致性问题。

spring的@Transactional本地处理方案(利用spring本身对数据库事务管理封装):
举例:teacher-service系统中插入teacher。admin-service系统中插入user。

@Transactional(rollbackFor = CommonException.class)
@Override
public ResultModel<String> addUser(@NonNull String username, @NonNull String password, @NonNull Integer roleId) throws CommonException {
    ResultModel<String> resultModel = new ResultModel<>();
    String userId = UUID.randomUUID().toString().replace("-", "");

    teacherFeign.addTeacher(username, userId);

    if (username.equals("李四")) {
        throw new CommonException("该名称已存在");
    }

    User user = new User();
    user.setId(userId);
    user.setUsername(username);
    user.setPassword(password);
    user.setRoleId(roleId);
    userMapper.insert(user);

    resultModel.setMsg("新增一条记录");
    resultModel.setRes(userId);
    return resultModel;
}

admin-service抛出了异常,但是teacher-service服务已经插入成功,不会回滚,数据不一致。可见@Transactional只能保证单点数据库事务,无法保证分布式事务一致性。

什么是分布式事务?


分布式事务,就是在分布式系统中运行的事务,使用多个数据源,由多个本地事务组合而成。在分布式场景下,对事务的处理操作可能来自不同的机器,甚至是来自不同的操作系统,保证数据一致性。

分布式事务解决方案


2PC - 二阶段提交算法
3PC - 三阶段提交算法
TCC - 补偿事务
SAGA事务
AT事务
本地消息表

2PC - 二阶段提交算法


节点分为协调者和参与者,执行分为提交事务请求阶段、提交事务执行阶段(投票、执行)。
  1. 阶段1:
    协调者发送一个事务询问给参与者,询问参与者是否接受。参与者执行事务操作,将undo和redo信息写入事务日志,然后向协调者回复yes或者no响应。
  2. 阶段2:
    协调者根据参与者反馈,提交或者中止当前事务,如果参与者全都yes,那么就提交执行该事务。但是只要有一个参与者回复no或者等待超时,那么参与者中断当前事务。然后向所有参与者节点发送rollback请求,利用undo信息来执行事务回滚操作,然后释放资源,向协调者发送ACK请求。

2PC缺陷:

  • 同步阻塞:参与该事务的逻辑,在事务处理期间都将是阻塞的。
  • 太过保守:一个节点出现一点问题,那么整个所有的节点都需要回滚(缺乏容错机制)。
  • 单点问题:2PC的整个流程过于依赖协调者,如果协调者第二阶段发生了问题,那么当前事务相关的所有参与者都将处于阻塞状态,无法完成事务操作。
  • 脑裂问题:可能由于网络原因,网络不好的节点没有进行事务处理,而网络正常的节点进行了事务处理,造成了数据不一致。

3PC - 三阶段提交算法


3PC是2PC的改进版,将请求提交的过程一分为二。
  1. 阶段1:CanCommit
    事务询问:协调者向参与者发送一个CanCommit事务请求,询问是否可以执行事务提交操作,开始等待参与者的响应。
    参与者向协调者反馈事务询问响应:参与者根据自身情况,反馈YES响应,进入预备状态,否则返回NO响应。
  2. 阶段2:PreCommit
    返回yes情况:
    协调者向所有参与者发送PreCommit请求,进入准备阶段。
    参与者收到PreCommit请求后,执行事务操作,将undo和redo信息记录到日志中。
    各参与者向协调者反馈事务执行响应:成功响应ACK,同时等待最终指令:提交还是终止。
    返回no情况(中断事务):
    任一参与者向协调者反馈了NO响应或者等待超时之后,协调者无法接收到所有参与者反馈响应,那么中断事务。
    发送中断请求(abort请求)。
    参与者收到协调者abort请求或者等待协调者请求超时,参与者中断事务。
  3. 阶段3:DoCommit
    同步处理:
    发送提交请求:协调者正常工作状态,接收到来自所有参与者的ACK响应,那么它将从预提交状态转换为提交状态,向所有参与者发送DoCommit请求。
    事务提交:参与者收到DoCommit请求后,会正式执行事务提交操作,完成提交后,释放事务资源。
    反馈事务提交结果:参与者完成事务提交之后,向协调者发送ACK消息。
    完成事务:协调者收到所有参与者反馈的ACK消息后,完成事务。
    回滚处理:
    发送中断请求:协调者向所有参与者发送abort请求。
    事务回滚:参与者收到abort请求后,利用 阶段2中的undo日志来执行事务回滚操作,完成回滚,释放资源。
    反馈事务回滚结果:参与者完成了事务回滚后,向协调者发送ACK消息。
    协调者收到所有参与者反馈的ACK消息后,中断事务。

3PC优缺点:

  • 优点:减小了阶段阻塞的范围。
  • 缺点:当第二阶段PreCommit成功之后,第三阶段协调者向参与者发送DoCommit之后,然后参与者同步,但是如果同步之后,参与者与协调者断开了。那么协调者一直收不到参与者回复,那么就超时。协调者开始发送Abort回滚操作,其他参与者都回滚了,而断开的参与者没有回滚,造成了服务器节点之间数据不一致。

TCC - 补偿事务


思路:
针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。将各自资源情况先开展调查,然后交给TCC事务管理器来管理,统一处理。
三个阶段:
Try阶段:主要是对业务系统做检测及资源预留
Confirm:主要是对业务系统做确认提交
Cancel:主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

还以前面的admin-service和teacher-service举例
举例:
admin-service 的try阶段:
将admin-service新增接口服务先冻结
检查用户表中是否已经存A,验证存入的A的有效性,然后将新增的记录写入消息日志中。
admin-service 的confirm阶段:
不做操作。
admin-service 的cancel阶段:
从日志和消息中,消费消息,将新增的记录A回滚。

teacher-service 的try阶段:
检查教师表中是否已经存B,验证存入的B的有效性,然后将新增的记录写入消息日志中。
teacher-service 的confirm阶段:
读取日志消息,教师表新增记录B。否则读取日志消息,教师表不新增记录B。
teacher-service 的cancel阶段:
不做操作。

优点:
隔离性强、在业务执行的时候,只操作预留资源,几乎不会涉及到资源的争用,所以性能较高。
缺点:
业务侵入性高,开发成本高。

SAGA事务


思路:SAGA 事务相比于TCC事务,就是将大事务拆分成每个系统服务小事务,然后发生错误,不采用TCC的回滚,而是采取给予补偿,所以也不需要冻结。
正向补偿:如果某个子事务提交失败,则一直对该事务进行重试,直至成功为止。
反向补偿:如果某个子事务提交失败,则对该子事务及其之前所有的子事务进行补偿操作。
总的来说SAGA相较于TCC,就是补偿代替回滚。

AT事务


AT事务参照2PC算法。AT事务的思路就是快照思路。
业务数据提交时,自动拦截所有的SQL,分别保存SQL对数据修改前后的快照。
如果分布式事务成功,那么直接删除快照中的记录。
如果分布式事务失败,那么事务回滚,根据日志数据自动产生用于补偿的逆向SQL。

本地消息表


思路:就是将分布式事务拆分成本地事务处理,通过一个本地消息表来维护事务的处理情况,本地消息表像对账功能一样。
  • 消息生产者:
    额外设计一个本地消息表,用于记录消息的处理情况,和本地业务处理都在同一个事务中。生产消息到队列,消息如果生产失败,还要重试发送。
  • 消息消费者:
    消费者消费消息,完成自己业务逻辑,将记录写到数据库。如果写成功,那么将队列中的消息删除。如果写失败,那么本地数据库回滚。然后写一条回滚消息到消息队列。生产者消费这条回滚消息,然后将本地数据回滚。

生产者定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。
消费者定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。

参考


凤凰架构之分布式事务
Spring 事务常见错误
RocketMQ与Kafka中如何实现事务
分布式事务最全解决方案

相关文章

  • 分布式事务的解决方案

    本文从以下几个方面介绍分布式事务的解决方案: 为什么会有分布式事务分布式事务经典模型分布式事务解决方案 为什么会有...

  • 分布式事务

    目录 分布式事务解决方案 长事务: saga 短事务: 设计的时候尽量短事务,能不用分布式事务尽量不用,分布式事务...

  • 微服务中分布式事务解决方案

    分布式事务解决方案 1、阿里巴巴seata分布式事务 2、 京东ShardingSphere分布式事务 3、tcc...

  • 微服务 14:初探微服务分布式事务 - Seata

    1:什么是事务,什么是ACID 2:什么是分布式事务 3:分布式事务解决方案 4:Seata 分布式事务框架 5:...

  • 常用的分布式事务解决方案

    常用的分布式事务解决方案 再有人问你分布式事务,把这篇扔给他

  • seata AT模式

    描述 seata是分布式事务解决方案。分布式事务是包含若干分支事务的全局事务。如果各分支事务提交成功,则全局事务提...

  • 分布式事务解决方案

    分布式事务解决方案 分布式事务的主要解决方案 XA方案 - 两阶段提交方案 TCC方案 本地消息表 可靠信息最终一...

  • java分布式,最终一致性,java幂等问题分析

    分布式学习: 分布式常用的分布式事务解决方案介绍有多少种?基于 Redis 的分布式锁分布式简介关于分布式事务、两...

  • 分布式事务总结

    事务、分布式事务、Base、CAP不赘述。 业内场景的分布式事务解决方案有,2PC、3PCTCC(alipay)增...

  • 分布式事务(3)--seate

    Seate控制分布式事务:Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。...

网友评论

      本文标题:分布式事务解决方案

      本文链接:https://www.haomeiwen.com/subject/isiewrtx.html