edis0n0
V2EX  ›  数据库

屎山代码导致一部分用户付款后被扣除了两次余额,第二次扣款是没有创建余额变动记录的, mysql 如何快速找出这部分余额异常的用户?

  •  
  •   edis0n0 · Dec 2, 2022 · 5253 views
    This topic created in 1443 days ago, the information mentioned may be changed or developed.
    余额变动表有一亿条了,全遍历一遍感觉要很久,有没有效率高的方法?因为这个问题已经出现一天才收到反馈,很多用户在那之后又充值或付款了新订单,不能直接判断最后一次变动金额和当前余额相等。
    23 replies  •  2022-12-02 18:59:25 +08:00
    T0m008
    T0m008
    Dec 2, 2022
    1
    第二次扣款没有余额变动记录你怎么在余额变动表里找? mysql 这条路无解。

    先通过时间段把被扣款用户粗略筛选出来,然后再看能不能细分。
    eason1874
    eason1874
    Dec 2, 2022❤️1
    2
    一亿条也不是很多吧,先把这段时间付款的用户 ID 导出列表,然后分成几批同时跑,再慢,几个小时也该跑完了。有时候简单粗暴的方法就是最快的方法
    danhahaha
    danhahaha
    Dec 2, 2022 via iPhone
    3
    直接去访问记录里面找出访问过下单界面的用户
    bao3
    bao3
    Dec 2, 2022 via iPhone
    4
    我和二楼的疑问一样
    leaves615
    leaves615
    Dec 2, 2022
    5
    测试不到位。
    bthulu
    bthulu
    Dec 2, 2022
    6
    既然第二次扣款是没有创建余额变动记录的, 那不就相当于没有扣款么, 那你什么都不用干就行了, 反正用户余额也没变少, 你们的余额也没增加.
    Xusually
    Xusually
    Dec 2, 2022 via iPhone❤️1
    7
    @bthulu op 是说钱多扣了,但是扣款记录没有,余额已经少了
    Glkcv
    Glkcv
    Dec 2, 2022
    8
    把收款方流水拿出来,再把用户收款流水拿出来,对比一下
    wqhui
    wqhui
    Dec 2, 2022
    9
    第一次付款后余额是 A ,该用户下一次有记录的充值 /付款订单,变动前余额是 B ,那么造成 A 到 B 的差额订单就是丢失了
    mg52033
    mg52033
    Dec 2, 2022
    10
    @Lexgni 他这个估计是自建的钱包
    pjntt
    pjntt
    Dec 2, 2022
    11
    如果确认是第二扣款没有记录的。那就找交易流水,把有 2 次及以上的交易用户就是异常的。
    8355
    8355
    Dec 2, 2022❤️1
    12
    如 2 楼所说确实 你能确定明确的时间筛出来最后其实没多少
    救火任务要先考虑救火方式 先修 bug 再捞数据
    看一遍代码才能了解问题出在哪里 之后根据现有表结构和数据去排查
    起码是不是先把并发锁和事务加上。。。。
    changyang
    changyang
    Dec 2, 2022❤️1
    13
    这个要看余额变动表里面有没有记录本次扣除后剩余余额,如果记录的了的话就能根据这个剩余余额查询。
    假设
    用户表 user:
    userId 用户 id
    money 剩余金额

    余额变动表 moneyChage:
    userId 用户 id
    createTime 创建时间
    lastMoney 扣除后剩余金额
    deductMoney 本次扣除金额

    1 ,先查询最近一天的订单(问题以来的)
    2 ,查询这些订单所属用户。userList
    3 ,循环查询用户的余额变动记录,查询有问题的用户
    for user in userList
    userMoneyChangeList = queryUserMoneyChangeListDescByCreateTime(userId) (以创建时间倒排)
    lastMoney = user.money
    for changeItem in userMoneyChangeList
    if lastMoney != changeItem.lastMoney:
    print("该用户余额不符,userId: %s" , user.userId)
    lastMoney = lastMoney + deductMoney
    changyang
    changyang
    Dec 2, 2022
    14
    以上还可以优化一下 queryUserMoneyChangeListDescByCreateTime 方法,在 sql 中只限定查询问题时间以来的
    jorneyr
    jorneyr
    Dec 2, 2022❤️1
    15
    以前参与的英国电商项目,异常没处好导致给客户信用卡扣款 150 多次,直到额度不够。
    时不时发生,几年了这个 Bug 没解决掉,把钱还给客户就解决了问题。
    changyang
    changyang
    Dec 2, 2022
    16
    如果嫌慢可以加入线程,查询出 userList 后,把 userList 切分成 N 组放入线程任务中进行查询最后组合,会更快。
    Huelse
    Huelse
    Dec 2, 2022
    17
    有日志吗?
    wudi77
    wudi77
    Dec 2, 2022
    18
    查交易流水,比对
    dcsuibian
    dcsuibian
    Dec 2, 2022
    19
    这个帖子能有效降低我写出 bug 时的愧疚感
    joApioVVx4M4X6Rf
    joApioVVx4M4X6Rf
    Dec 2, 2022
    20
    想知道楼主是怎么解决这个问题的
    edis0n0
    edis0n0
    OP
    Dec 2, 2022
    21
    @v2exblog 就是 2 和 13 楼的办法
    fackVL
    fackVL
    Dec 2, 2022 via iPhone
    22
    余额变动表肯定有扣除后的余额啊,找最后一条变动记录的最后余额和钱包余额做对比就行了呗
    dorothyREN
    dorothyREN
    Dec 2, 2022
    23
    直接对比 binlog 吧, 有 binlog 没有变动记录就是异常用户
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   967 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 57ms · UTC 20:53 · PVG 04:53 · LAX 12:53 · JFK 15:53
    ♥ Do have faith in what you're doing.