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

    分布式事务

    (!!!最后防线,对账!!!, 注意采用幂等性)

    1、两阶段提交协议 2PC (prepare, commit)《MYSQL支持》

    一个协调者、多个参与者

    • 准备阶段:协调者通知参考者,执行准备提交;有失败则统一通知回滚
    • 提交阶段:协调者通知参考者,执行提交;有失败则统一通知回滚
    缺点:
    1、同步阻塞、执行过程中所有资源都处理同步阻塞
    2、单点故障、由于协调者是单点,出现故障参与者都无法执行
    3、数据不一致、当协调者在通知提交时,它与某个参与者网络断开,导致某个参与者无法联系,出现分布式系统数据不一致
    
    <?PHP
    $dbtest1 = new mysqli("172.20.101.17","public","public","dbtest1")or die("dbtest1 连接失败");
    $dbtest2     = new mysqli("172.20.101.18","public","public","dbtest2")or die("dbtest2 连接失败");
    
    //为XA事务指定一个id,xid 必须是一个唯一值。
    $xid = uniqid("");
    
    //两个库指定同一个事务id,表明这两个库的操作处于同一事务中
    $dbtest1->query("XA START '$xid'");//准备事务1
    $dbtest2->query("XA START '$xid'");//准备事务2
    
    try {
        //$dbtest1
        $return = $dbtest1->query("UPDATE member SET name='唐大麦' WHERE id=1") ;
        if($return == false) {
           throw new Exception("库dbtest1@172.20.101.17执行update member操作失败!");
        }
    
        //$dbtest2
        $return = $dbtest2->query("UPDATE memberpoints SET point=point+10 WHERE memberid=1") ;
        if($return == false) {
           throw new Exception("库dbtest1@172.20.101.18执行update memberpoints操作失败!");
        }
    
        //阶段1:$dbtest1提交准备就绪
        $dbtest1->query("XA END '$xid'");
        $dbtest1->query("XA PREPARE '$xid'");
        //阶段1:$dbtest2提交准备就绪
        $dbtest2->query("XA END '$xid'");
        $dbtest2->query("XA PREPARE '$xid'");
    
        //阶段2:提交两个库
        $dbtest1->query("XA COMMIT '$xid'");
        $dbtest2->query("XA COMMIT '$xid'");
    } 
    catch (Exception $e) {
        //阶段2:回滚
        $dbtest1->query("XA ROLLBACK '$xid'");
        $dbtest2->query("XA ROLLBACK '$xid'");
        die($e->getMessage());
    }
    
    $dbtest1->close();
    $dbtest2->close();
    
    ?>
    

    2、三段提交 3PC (CanCommit、PreCommit、DoCommit)

    就是把二阶段提交中的第一阶段(准备阶段)分为2阶段,这样就有了CanCommit、PreCommit、DoCommit三个阶段.(没有解决啥问题,加点东西就改进了?)

    3、补偿事务TCC(Try, Commit,Cancel)

    以转账为例。

    • Try, 准备或者预处理, 冻结资金

    • Commit, 提交, 扣除资金

    • Cancel, 补偿处理, 出现异常时, 反向加一笔资金平账。

    优点:比二段式简单
    缺点:2、3两步都可以出现失败,出现数据不一致
    

    4、本地消息表

    将分布式事分拆分成多个本地事务, 生产者和消费都都有业务表,都额外创建一个消息表,都有一个定时检查器。生产者与消费者通过MQ连接。

    • 生产者,处理本地事务,<处理业务,添加对应消息>, 通知消息到消费者,失败则重试
    • 消费者, 处理消息成功,则完成;失败则重试;如果业务失败,则通知生产者反向补平。
    • 双方定时扫描消息表, 重发未完成或者失败的消息。
    优点:避免了分布式事务所,实现最终一致性
    缺点:消息表会业务耦合到系统中,各种耦合表;还有定时器扫描消耗
    

    5、Rocket MQ事务消息

    为了解决本地消息表中的缺陷,消除消息表。RocketMQ提出了”事务消息“的概念

    1、发送Prepare消息

    2、Update DB

    3、根据update db结果成功或者失败,Confirm或者取消消息

    // ==============发送事务消息的一系列准备工作=======
    // 未决事务,MQ服务器回查客户端
    // 也就是上文所说的,当RocketMQ发现`Prepared消息`时,会根据这个Listener实现的策略来决断事务
    TransactionCheckListener transactionCheckListener = new TransactionCheckListenerImpl();
    // 构造事务消息的生产者
    TransactionMQProducer producer = new TransactionMQProducer("groupName");
    // 设置事务决断处理类
    producer.setTransactionCheckListener(transactionCheckListener);
    // 本地事务的处理逻辑,相当于示例中检查Bob账户并扣钱的逻辑
    TransactionExecuterImpl tranExecuter = new TransactionExecuterImpl();
    producer.start()
    // 构造MSG,省略构造参数
    Message msg = new Message(......);
    // 发送消息
    SendResult sendResult = producer.sendMessageInTransaction(msg, tranExecuter, null);
    producer.shutdown();
    
    //  ==================事务消息的发送过程========
    public TransactionSendResult sendMessageInTransaction(.....)  {
        // 逻辑代码,非实际代码
        // 1.发送消息
        sendResult = this.send(msg);
        // sendResult.getSendStatus() == SEND_OK
        // 2.如果消息发送成功,处理与消息关联的本地事务单元
        LocalTransactionState localTransactionState = tranExecuter.executeLocalTransactionBranch(msg, arg);
        // 3.结束事务
        this.endTransaction(sendResult, localTransactionState, localException);
    }
    

    最终人工对账,补偿,成本远低于完整的自动化分布式事务回滚!!!!

  • 相关阅读:
    信息系统开发平台OpenExpressApp - 支持列表分组(Group)
    WPF - 轻量级的开源XAML编辑器Kaxaml
    工作流 - 架构描述
    工作流 - 技术备忘录
    开源 - 轻型的表达式引擎 Flee
    敏捷实践(收集)
    人生就是......
    信息系统开发平台OpenExpressApp - 应用模型ApplicationModel
    软件观点 - 平台分类:系统平台、开发平台和开放平台
    软件产品线工程方法 - BAPO之架构(Architecture)
  • 原文地址:https://www.cnblogs.com/freebird92/p/9857374.html
Copyright © 2011-2022 走看看