• 分布式事务


    事务介绍(引用百度百科):

      数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性

    传统单机事务:

    示例业务逻辑步骤:创建订单请求到达,订单系统需要执行1.生成订单,2.锁定优惠券,3.锁定贷款券

    代码模型:

     1 public Result createOrder(){
     2     ...
     3     saveOrder();
     4     ...
     5 }
     6 
     7 @Transaction
     8 private void saveOrder(){
     9     1.生成订单
    10     Order orde = saveOrder();
    11     2.优惠券
    12     lockCouponNumber();
    13     3.贷款券
    14     lockLoanNumber();
    15 }

    由于1、2、3都在本地事内,所以一旦任何一步操作出现异常,都会回滚,满足acid

    soa化之后:

    随着公司体量发展,订单系统日益庞大,造成维护、测试不便,所以要进行拆分,拆分后架构如下:

    代码如下:

    1 @Transaction
    2 public void saveOrder(){
    3     1.生成订单
    4     Order orde = saveOrder();
    5     2.锁定优惠券
    6     invokeLockCouponNumber();
    7     3.锁定贷款券
    8     invokeLockLoanNumber();
    9 }

    问题:

    在分布式系统中,每一个机器节点虽然都能明确的知道自己执行的事务是成功还是失败,但是却无法知道其他分布式节点的事务执行情况。比如:假设1和2执行成功,3失败,就导致最终状态不一致

    分布式事务解决方案:

    eBay在2008年公布了一个关于BASE准则提到一个分布式事务解决方案。eBay的方案其实是一个最终一致性方案,它主要采用消息队列来辅助实现事务控制流程

    示例:

     1 createOrder(){
     2     try{
     3         ...
     4         saveOrder();
     5         ...
     6     }catch(Exception e){
     7         //发送rmq消息、优惠券、贷款券系统收到消息后,解绑
     8         sendCreateFailMsg();
     9     }
    10 }
    11 
    12 @Transaction
    13 private void saveOrder(){
    14     1.生成订单
    15     Order orde = saveOrder();
    16     2.锁定优惠券
    17     invokeLockCouponNumber();
    18     3.锁定贷款券
    19     invokeLockLoanNumber();
    20 }

    捕获到saveOrder异常后,发送创建订单失败的消,优惠券、贷款券系统订阅此消息,收到消息后做解绑操作。

    需要解决的问题:

    1,创建订单失败的消息发送失败 2,消息丢失 3,重复消费

    对于1,有同学可能会想到事务消息,但在此业务场景并不适用,我的一个方案:将消息体等信息存放在数据库中,由定时器执行

    对于2,现在用的比较普遍的MQ都具有持久化消息的功能,如果消费者宕机或者消费失败,都可以执行重试机制

    对于3,方案一:保证幂等性,例记录执行后将rocketmq的messageId,kafka的话,将消费组名+parttition+offet组成唯一的key记录在数据库中

    保证最终一致性的模式

    1.    查询模式

    任何一个服务操作都提供一个查询接口,用来向外部输出操作执行的状态。服务操作的使用方可以通过接口得知服务操作执行的状态,然后根据不同状态做不同的处理操作 为了能够实现查询,每个服务操作都需要有唯一的流水号,例如微信支付的订单查询接口

    2.    补偿模式

    有了查询模式,我们就能够得知操作所处的具体状态,如果整个操作处于不正常状态,我们需要修正操作中的出现问题的子操作。也许是要重新执行,或者取消已完成的操作。通过修复使得整个分布式系统达到最终一致。这个过程就是补偿模式。例如:系统异常,发出报警邮件,通知技术人员手动处理等

    根据发起形式又分为

    自动恢复:通过对发生失败操作的接口自动重试或者回滚已经完成的操作

    通知运营:如果程序无法自动完成恢复,则通过运营人员手动进行补偿

    通知技术:通过监控或者告警通知到技术人员,通过技术手段进行修复

    CAP原则(CAP定理)、BASE理论

    CAP原则  

    CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得   。

    BASE

    BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写,BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

  • 相关阅读:
    《Java并发编程的艺术》 第9章 Java中的线程池
    《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类
    java锁总结
    《Java并发编程的艺术》第5章 Java中的锁 ——学习笔记
    《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记
    Java并发编程的艺术(一、二章) ——学习笔记
    redis缓存使用SpringDataRedis
    商城06——solr索引库搭建&solr搜索功能实现&图片显示问题解决
    商城05——首页轮播图显示实现&Redis环境搭建&Redis实现缓存
    商城04——门户网站介绍&商城首页搭建&内容系统创建&CMS实现
  • 原文地址:https://www.cnblogs.com/chinano1/p/10014439.html
Copyright © 2020-2023  润新知