zoukankan      html  css  js  c++  java
  • SpringCloud分布式事务的解决方案

    常见的分布式解决方案

    1、两阶段提交协议(2PC)

      解决分布式系统的数据一致性问题出现了两阶段提交协议(2 Phase Commitment Protocol),

    两阶段提交由协调者和参与者组成,共经过两个阶段和三个操作,部分关系数据库如Oracle、MySQL支持两阶段提交协议。

    说到2pc就不得不聊聊数据库分布式事务中的XA transactions

    在XA协议中分为两阶段:

    • 第一阶段:事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
    • 第二阶段:事务协调器要求每个数据库提交数据,或者回滚数据。

    举一个例子:

    1、应用程序通过事务协调器向两个库发起prepare,两个数据库收到消息分别执行本地事务(记录日志),

      但不提交,如果执行成功则回复yes,否则回复no。

    2、事务协调器收到回复,只要有一方回复no则分别向参与者发起回滚事务,参与者开始回滚事务。

    3、事务协调器收到回复,全部回复yes,此时向参与者发起提交事务。

      如果参与者有一方提交事务失败则由事务协调器发起回滚事务。

    优点:

      尽量保证了数据的强一致,实现成本较低,在各大主流数据库都有自己实现,对于MySQL是从5.5开始支持

    缺点:

    单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,

      在第二阶段正准备提交的时候事务管理器宕机,资源管理器就会一直阻塞,导致数据库无法使用。

    同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。

    数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能,比如在第二阶段中,

    假设协调者发出了事务commit的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了commit操作,

    其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。

    2、事务补偿(TCC)

      TCC事务补偿是基于2PC实现的业务层事务控制方案,它是Try、Confirm和Cancel三个单词的首字母,含义如下:

    • 1、Try 检查及预留业务资源完成提交事务前的检查,并预留好资源。
    • 2、Confirm 确定执行业务操作,对try阶段预留的资源正式执行。
    • 3、Cancel 取消执行业务操作,对try阶段预留的资源释放。

    TCC方案在电商、金融领域落地较多。TCC方案其实是两阶段提交的一种改进。

    其将整个业务逻辑的每个分支显式的分成了Try、Confirm、Cancel三个操作。

    Try部分完成业务的准备工作,confirm部分完成业务的提交,cancel部分完成事务的回滚。

    基本原理如下图所示。

    事务开始时,业务应用会向事务协调器注册启动事务。之后业务应用会调用所有服务的try接口,

    完成一阶段准备。之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。

    如果接口调用失败,会进行重试。

    举一个例子:下单减库存的业务

    1、Try

    下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。

    订单服务检查当前是否满足提交订单的条件(比如:当前存在未完成订单的不允许提交新订单)。

    库存服务检查当前是否有充足的库存,并锁定资源。

    2、Confirm

    订单服务和库存服务成功完成Try后开始正式执行资源操作。

    订单服务向订单写一条订单信息。

    库存服务减去库存。

    3、Cancel

    如果订单服务和库存服务有一方出现失败则全部取消操作。

    订单服务需要删除新增的订单信息。

    库存服务将减去的库存再还原。

    优点:

    最终保证数据的一致性,在业务层实现事务控制,灵活性好。

    缺点:

    开发成本高,每个事务操作每个参与者都需要实现try/confirm/cancel三个接口。

    注意:

    TCC的try/confirm/cancel接口都要实现幂等性(幂等性是指同一个操作无论请求多少次,其结果都相同。),

    在为在try、confirm、cancel失败后要不断重试。

    3、消息队列实现最终一致

      本方案是将分布式事务拆分成多个本地事务来完成,并且由消息队列异步协调完成,如下图:下边以下单减少库存为例来说明:

    1、订单服务和库存服务完成检查和预留资源。

    2、订单服务在本地事务中完成添加订单表记录和添加“减少库存任务消息”。

    3、由定时任务根据消息表的记录发送给MQ通知库存服务执行减库存操作。

    4、库存服务执行减少库存,并且记录执行消息状态(为避免重复执行消息,在执行减库存之前查询是否执行过此消息)。

    5、库存服务向MQ发送完成减少库存的消息。

    6、订单服务接收到完成库存减少的消息后删除原来添加的“减少库存任务消息”。

    实现最终事务一致要求:预留资源成功理论上要求正式执行成功,如果执行失败会进行重试,要求业务执行方法实现幂等。

    优点 :

    由MQ按异步的方式协调完成事务,性能较高。

    不用实现try/confirm/cancel接口,开发成本比TCC低。

    缺点:

    此方式基于关系数据库本地事务来实现,会出现频繁读写数据库记录,浪费数据库资源,另外对于高并发操作不是最佳方案。

  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/64Byte/p/13357887.html
Copyright © 2011-2022 走看看