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

彦祖们,请教下这个问题有什么好的解决方案?

  •  
  •   MeloForsaken · 2021-02-25 10:52:00 +08:00 · 1723 次点击
    这是一个创建于 1365 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有两个部署在不同服务器的系统 A 、B (对应的数据库也是分开的)。

    正常情况:A 向 B 发请求,B 写数据库,A 根据 B 回传的信息写数据库。

    现在 A 因为偶尔的网络问题没有收到 B 回传的信息,导致 B 写了数据库,A 没有写数据库,造成数据不一致。

    请教下有什么方案解决这种事务问题?(网络问题不可解决的情况下)

    xiaofan2
        1
    xiaofan2  
       2021-02-25 11:03:11 +08:00
    我理解你这个就相当于一个重试机制如何做幂等的问题?用订单号?每次 A 给 B 的请求都带订单号 B 写库之前查询一次是否存在
    MeloForsaken
        2
    MeloForsaken  
    OP
       2021-02-25 11:13:41 +08:00
    @xiaofan2 你的意思是 A 需要加上重试机制,保证出现网络异常的时候重复向 B 发请求,同时 B 写库前加上校验?
    jmyz0455
        3
    jmyz0455  
       2021-02-25 11:16:23 +08:00
    单纯为标题顶一下贴🤣
    Twain
        4
    Twain  
       2021-02-25 11:23:24 +08:00
    1.业务如果是乐观性的,可以先写库,双方加一个轮询检测机制,设定时间内如果没有回执,就认为任务失败,回退下数据库
    2.业务如果是悲观性的,那就要双发互发回执确认之后,才能写库了
    yuchting
        5
    yuchting  
       2021-02-25 11:28:24 +08:00
    重试其实不是重要的,必须要重试。
    重点是,为每一个请求、应答加一个唯一 hash,然后每次处理需要 hash 比对、存库( memcache )。
    否则,在事务中等待应答,效率太低。
    jjwjiang
        6
    jjwjiang  
       2021-02-25 11:31:36 +08:00
    你当然可以实现 B 的回滚,A 收不到反馈时让 B 进行回滚
    或者 B 收到 A 的回执时再真正插入并再次发送回执让 A 真正插入

    但是既然你有这样的网络问题,那以上任何解决方案都是不可靠的,因为任何策略都基于多次网络通信,你单次通信都不能保证到达,怎么保证这些多次网络通信可靠呢?

    在 AB 的通信不能保证的情况下,只能再找一个双方都能访问的第三方用来做中介了,比如 MQ 或者数据库,双方都监听或者轮询这个第三方来做确认。
    GGGG430
        7
    GGGG430  
       2021-02-25 11:36:47 +08:00 via iPhone
    分布式事务解决方式,要么 tcc 三段提交,要么 mq 消息队列
    yedan1206
        8
    yedan1206  
       2021-02-25 11:37:03 +08:00
    使用消息队列中间件可完美解决
    theOneMe
        9
    theOneMe  
       2021-02-25 11:39:09 +08:00
    上 mq 吧,做解耦,最终一致就行
    bitcapybara
        10
    bitcapybara  
       2021-02-25 11:47:24 +08:00
    分布式事务不就是用来干这个的吗?已经有很多成熟的框架了啊
    markgor
        11
    markgor  
       2021-02-25 13:14:01 +08:00
    A 发送信息给 B,B 处理完返回结果给 A,
    当出现异常的时候,B 写入了但没返回给 A,
    那么 A 通过异常机制启动重试机制,
    只要 B 是有做幂等那就不会重复插入了。
    v2orz
        12
    v2orz  
       2021-02-25 14:35:35 +08:00
    做最终一致的话,b 回传用 mq 即可
    强一致的话,不考虑分布式事务的基础上,可以 B 做接口冥等,A 没有收到信息的情况下反复重试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1800 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:28 · PVG 00:28 · LAX 08:28 · JFK 11:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.