zoukankan      html  css  js  c++  java
  • 分布式系统事务

    何有此问:

    我们的系统,使用面向服务的架构,将业务分解为多个dubbo服务。当一个业务需要多个dubbo服务协作时,如何确保数据的一致性?

    一、目标

    何为分布式事务;为何需要分布式事务;如何实现分布式事务。

    1、何为分布式事务

    在一个仅有一个数据库的系统中,实现事务的控制方式为:DBMS。(spring事务管理的本质也是使用数据库对事务的支持)

    在一个拥有多个数据库的系统中,如何跨库进行事务的控制,这就是分布式事务。(在此不讨论spring多数据源事务的情况)

    使用dubbo进行面向服务的架构(SOA),也需要分布式事务。

    2、为何需要分布式事务

    以公司系统为例,数据库有:订单库(ORDERS),会员库(MEMBER)。当一笔交易成功时,需要跨库修改对应表的相关字段。此时如何保证数据的一致性?这就需要到分布式事务来进行控制。

    3、如何实现分布式事务

    关系型数据库通常具有ACID特性:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)。

    在分布式系统中,CAP理论三选二,而P(分区性)必选,剩下二选一,只能在C(一致性)、A(可用性)当中进行选择。

    BASE理论解决了CAP理论中一致性和可用性二选一的问题。

    BASE模型:

    (1)基本可用。(BA:Basically Available)

    (2)软状态,有一段时间不同步。(S:Soft State)

    (3)最终一致。(E:Eventually Consistent)

    典型的分布式事务解决方案包含以下方式:

    (1)两阶段提交(2PC,Two Phase Commit)(基础)

    (2)本地消息表(异步确保数据的一致性)

    二、原理

    1、经典的(2PC)

    引入协调者和参与者的概念,各个参与者将自己的操作结果通知协调者,再由协调者根据反馈来的结果,决定参与者下一步是进行提交还是终止。

    所谓两阶段提交,就是将整个过程分解为两个阶段:1、准备阶段。2、提交阶段。

    步骤为:

    1、准备阶段:协调者将需要执行的操作分发给各个参与者,参与者执行相应操作,未进行事务的提交,然后返回操作结果。

    2、提交阶段:协调者收集各个参与者的操作结果,如果全部成功,则通知参与者进行提交,否则通知参与者进行事务的回滚。

    特点:强一致性。

    缺点:

    1、同步阻塞,性能较差。

    2、根据CAP理论,可用性差。

    3、协调者存在单点问题。

    4、无法解决的问题:协调者与参与者在提交阶段宕机,那么就无法知晓事务的处理结果。

    2、本地消息表

    将分布式事务拆分为本地事务。

    步骤:

    1、消息生产方,需要建立一个消息表,该表记录需要执行的业务以及业务执行的状态。消息表和业务数据在一个事务里提交,由本地事务提供事务控制。

    2、消息消费方,也需要建立一个消息表,该表记录已经执行成功的消息。消息表和消费方在同一个事务里,也由本地事务提供事务控制。

    3、生产方和消费方,根据生产消息表,消费消息表,进行数据的一致性校验。

    特点:最终一致性。

    缺点:

    1、消息表耦合到业务系统中。

     

    三、本地消息表的实现:

    本地消息表:
    1)、消息生产方:消息表AM,业务表AB。在A数据库中,控制AM和AB的事务。
    2)、消息消费方:消息表BM,业务表BB。在B数据库中,控制BM和BB的事务。

    举个栗子:
    业务场景:
    数据库:A,B。
    表:AM(A库中的消息表),AB(A库中的业务表),BM(B库消息表),BB(B库业务表)。
    需要同时在AB表、BB表中,各插入一条数据。
    操作步骤:
    1)、在AB表中插入数据,且在AM表中插入需要在BB表中完成的操作。
    2)、有一个定时任务,将AM表、BM表中的数据读取出来。对比两张表,如果BM表中没找到AM的对应记录。则在BB表中插入业务数据,如果插入成功,同时在BM表中插入执行成功的数据。
    3)、再开一个定时任务,将AM表和BM表中已经完成的记录,进行删除。删除时,应当先删除AM,再删BM。

     

     

  • 相关阅读:
    一天摄入多少蛋白质比较合理?
    给函数添加元数据(python)
    反转链表(C++实现)
    删除链表的中间节点(C++实现)
    在双向链表中删除倒数第K个链表节点(C++实现)
    在单链表中删除倒数第K个节点(C++实现)
    二叉树的创建及遍历(递归和非递归C++实现)
    删除排序数组中的重复项(C++实现)
    打印两个有序链表的公共部分(C++实现)
    用一个栈实现另一个栈的排序(C++实现)
  • 原文地址:https://www.cnblogs.com/chen--biao/p/9646734.html
Copyright © 2011-2022 走看看