V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
947211232
V2EX  ›  程序员

如何确保业务数据的同步、一致?

  •  
  •   947211232 · 2020-01-11 10:24:29 +08:00 · 4054 次点击
    这是一个创建于 1783 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 需求就是使用第三方平台的余额、积分、等级
    • 事务操作本地数据,若中间步骤同步出错该如何处理

    //开启事务
    
    //更新本地余额
    
    //更新本地积分
    
    //更新本地等级
    
    //同步到第三方余额
    if(异常){
    	//事务回滚
    }
    
    //同步到第三方积分 [若中间步骤同步失败,本地数据可以回滚,但第三方之前的已同步数据该如何处理] 
    if(异常){
    	//事务回滚
    }
    
    //同步到第三方等级
    if(异常){
    	//事务回滚
    }
    
    //提交事务
    
    第 1 条附言  ·  2020-01-11 11:53:44 +08:00
    * 第三方平台(微信)不可控
    * 虽然上述都可以调用第三方同一个 api,但考虑到往后的业务可能需要调用不同 api
    * 本地事务应该全部提交,调用第三方 api 写入标记、排入队列处理——已 get
    * 请说出您知道的思路 或者 您处理过的方案,蟹蟹
    15 条回复    2020-01-13 15:18:14 +08:00
    947211232
        1
    947211232  
    OP
       2020-01-11 10:27:46 +08:00
    @全体成员
    ChoateYao
        2
    ChoateYao  
       2020-01-11 11:03:25 +08:00   ❤️ 1
    让第三方提供一个可以回滚的接口给你,如果回滚还是失败则记录日志,手动修复。
    tingfang
        3
    tingfang  
       2020-01-11 11:10:52 +08:00
    事物成功提交以后再调用第三方接口。
    tingfang
        4
    tingfang  
       2020-01-11 11:14:54 +08:00   ❤️ 1
    记一个"待调用第三方"的记录,定时任务扫表调用第三方。ps:调用第三方接口一般不应该放在事物内吧。。
    fcten
        5
    fcten  
       2020-01-11 11:18:01 +08:00   ❤️ 1
    本地完成就提交事务,但是标记成同步中。第三方请求添加到请求队列里,重试直至成功。第三方接口要保证幂等。
    如果第三方不在你的控制内,就别考虑回滚了。
    valeamoris
        6
    valeamoris  
       2020-01-11 11:34:37 +08:00   ❤️ 1
    如果是扣余额,你就本地先扣除余额,提交事务,然后调用第三方。如果是加余额,你可以先调用第三方,确定第三方调用成功,你这边再提交事务。
    947211232
        7
    947211232  
    OP
       2020-01-11 11:44:16 +08:00   ❤️ 1
    @ChoateYao 第三方叫微信 T T
    magicnobob
        8
    magicnobob  
       2020-01-11 12:42:32 +08:00
    保证最终一致性,一个出异常全部回滚,提供回滚的接口
    zunceng
        9
    zunceng  
       2020-01-11 13:40:08 +08:00   ❤️ 1
    同步做成 oplog 保证业务上同步到 oplog 不会出错

    由另一个流程单向同步 oplog 到第三方系统 这个流程失败的时候因为可以对单条记录回放 大不了手工处理
    zunceng
        10
    zunceng  
       2020-01-11 14:24:43 +08:00
    用 CAP 来解释就是 保证最终一致行 和 可用性 牺牲分区容错性
    mreasonyang
        11
    mreasonyang  
       2020-01-11 17:14:35 +08:00
    @zunceng 分区容错问题客观存在怎么牺牲,而最终一致性实际上是已经牺牲了一致性的
    CoderGeek
        12
    CoderGeek  
       2020-01-11 18:40:54 +08:00
    你是想要做到强一致 不容易、如果是最终一致 有不少方法可以实现
    xuanbg
        13
    xuanbg  
       2020-01-12 11:08:25 +08:00   ❤️ 1
    1、正常情况下,100%由系统提供一致性机制
    2、异常情况下,在复杂度可控的基础上尽可能由系统提供一致性机制
    3、无法由系统提供一致性机制的情况下,业务可中断、可回退的时候中断 /回退业务。
    4、业务不可中断 /回退的情况下,人工介入处理。
    ybonfire
        14
    ybonfire  
       2020-01-12 13:59:06 +08:00   ❤️ 1
    看这个业务应该是用户间独立的。能否把业务流程做成这样?

    1.事务完成前禁止读,防止读取到脏数据
    2.首先完成本地数据的修改
    3.调用第三方接口,如果接口是幂等的,调用失败则进行重试,如果超过最大重试次数则调用第三方接口进行反向操作,例如之前的操作是积分+15,反向操作则是积分-15 ;
    4.除非调用全部完成,或回滚全部完成,否则一直禁止读,这样做到强一致。如果是最终一直则不用这么麻烦,通过 RocketMQ 应该可以做到。
    ducklyl
        15
    ducklyl  
       2020-01-13 15:18:14 +08:00
    要么全做,做错回滚。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1029 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:28 · PVG 05:28 · LAX 13:28 · JFK 16:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.