• 一个较为健壮的下单方案


    一个较为健壮的下单方案

    最近在做的一个新项目中,有一个下单兑换的流程。用户的积分可以用来兑换物品。

    这个过程中,需要有几部分的操作:

    • 积分表扣除积分
    • 兑换表写用户兑换内容、状态
    • 下单
    • 更新用户兑换表为兑换完成状态

    这个流程中需要保证扣除积分后,能够为成功为用户下单。一个服务的调用会出现三种状态:成功、失败、超时。超时的情况下,是无法确定下单是否真正成功的,这时要避免重试时重复下单。为了保证下单流程的健壮性,除了下单接口本身需要做好幂等之外,上层业务本身也需要记录下单过程中的状态流转,方便进行下单后的逻辑处理,兑换表中需要一个状态字段,可能存在的几种状态为:

    • 1:扣除积分,未下单
    • 2:扣除积分,已经下单
    • 3:扣除积分,完成订单
    • 4:下单失败,积分回退

    通过数据库的事务,我们首先需要保证,下单出现非超时错误时,需要回滚下单之前的数据库操作:

    「 事务
    
    ​	     扣除积分
    
    ​        写兑换表,状态:1、扣除积分、已经下单
    
    」---> 下单失败,回滚事务
    

    下单成功自不用说,将兑换表中状态更新为3即可。当出现下单超时的时候,以上的事务就先不回滚了,通过消息队列来进行下单重试。消息队列的重试,也有可能再次出现超时的情况。队列的重试是有一定的时间间隔的,例如每隔/10/30/60秒重试一次。如果重试3次失败,应该有相应的告警出来,这时候一般是下游的订单服务不可用了。如果在重试下单时,出现了非超时错误,那么这时候应该给用户回退积分,并且将兑换表的状态更新为下单失败,金币回退。

    重试下单失败-->积分回退
    

    到这里其实已经可以较好地保证用户下单的健壮性的。但是还有一点,在成功下单后,需要更新用户的兑换表到状态3。这个时候有可能会抛出更新数据库表失败的异常,导致实际下单成功,但兑换表状态不一致的情况。解决的办法是当更新兑换表失败抛出异常时,捕获该异常,再利用消息队列发出更新数据库状态的消息,进行更新重试。整个流程如下所示:

    (完)

  • 相关阅读:
    使用强名称为程序集签名
    使用SN.exe对.Net生成的程序集进行签名
    .Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
    MongoDB查询
    mongo批量写入es
    用 Spark 处理复杂数据类型(Array、Map、JSON字符串等)
    kafka消费者
    kafka生产者
    Pyspark常用API总结
    selenium+chromedriver+python3 不加载图片
  • 原文地址:https://www.cnblogs.com/QG-whz/p/10584468.html
Copyright © 2020-2023  润新知