edis0n0
V2EX  ›  数据库

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

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

    先通过时间段把被扣款用户粗略筛选出来,然后再看能不能细分。
    eason1874
        2
    eason1874  
       Dec 2, 2022   ❤️ 1
    一亿条也不是很多吧,先把这段时间付款的用户 ID 导出列表,然后分成几批同时跑,再慢,几个小时也该跑完了。有时候简单粗暴的方法就是最快的方法
    danhahaha
        3
    danhahaha  
       Dec 2, 2022 via iPhone
    直接去访问记录里面找出访问过下单界面的用户
    bao3
        4
    bao3  
       Dec 2, 2022 via iPhone
    我和二楼的疑问一样
    leaves615
        5
    leaves615  
       Dec 2, 2022
    测试不到位。
    bthulu
        6
    bthulu  
       Dec 2, 2022
    既然第二次扣款是没有创建余额变动记录的, 那不就相当于没有扣款么, 那你什么都不用干就行了, 反正用户余额也没变少, 你们的余额也没增加.
    Xusually
        7
    Xusually  
       Dec 2, 2022 via iPhone   ❤️ 1
    @bthulu op 是说钱多扣了,但是扣款记录没有,余额已经少了
    Glkcv
        8
    Glkcv  
       Dec 2, 2022
    把收款方流水拿出来,再把用户收款流水拿出来,对比一下
    wqhui
        9
    wqhui  
       Dec 2, 2022
    第一次付款后余额是 A ,该用户下一次有记录的充值 /付款订单,变动前余额是 B ,那么造成 A 到 B 的差额订单就是丢失了
    mg52033
        10
    mg52033  
       Dec 2, 2022
    @Lexgni 他这个估计是自建的钱包
    pjntt
        11
    pjntt  
       Dec 2, 2022
    如果确认是第二扣款没有记录的。那就找交易流水,把有 2 次及以上的交易用户就是异常的。
    8355
        12
    8355  
       Dec 2, 2022   ❤️ 1
    如 2 楼所说确实 你能确定明确的时间筛出来最后其实没多少
    救火任务要先考虑救火方式 先修 bug 再捞数据
    看一遍代码才能了解问题出在哪里 之后根据现有表结构和数据去排查
    起码是不是先把并发锁和事务加上。。。。
    changyang
        13
    changyang  
       Dec 2, 2022   ❤️ 1
    这个要看余额变动表里面有没有记录本次扣除后剩余余额,如果记录的了的话就能根据这个剩余余额查询。
    假设
    用户表 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
        14
    changyang  
       Dec 2, 2022
    以上还可以优化一下 queryUserMoneyChangeListDescByCreateTime 方法,在 sql 中只限定查询问题时间以来的
    jorneyr
        15
    jorneyr  
       Dec 2, 2022   ❤️ 1
    以前参与的英国电商项目,异常没处好导致给客户信用卡扣款 150 多次,直到额度不够。
    时不时发生,几年了这个 Bug 没解决掉,把钱还给客户就解决了问题。
    changyang
        16
    changyang  
       Dec 2, 2022
    如果嫌慢可以加入线程,查询出 userList 后,把 userList 切分成 N 组放入线程任务中进行查询最后组合,会更快。
    Huelse
        17
    Huelse  
       Dec 2, 2022
    有日志吗?
    wudi77
        18
    wudi77  
       Dec 2, 2022
    查交易流水,比对
    dcsuibian
        19
    dcsuibian  
       Dec 2, 2022
    这个帖子能有效降低我写出 bug 时的愧疚感
    joApioVVx4M4X6Rf
        20
    joApioVVx4M4X6Rf  
       Dec 2, 2022
    想知道楼主是怎么解决这个问题的
    edis0n0
        21
    edis0n0  
    OP
       Dec 2, 2022
    @v2exblog 就是 2 和 13 楼的办法
    fackVL
        22
    fackVL  
       Dec 2, 2022 via iPhone
    余额变动表肯定有扣除后的余额啊,找最后一条变动记录的最后余额和钱包余额做对比就行了呗
    dorothyREN
        23
    dorothyREN  
       Dec 2, 2022
    直接对比 binlog 吧, 有 binlog 没有变动记录就是异常用户
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1543 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 16:31 · PVG 00:31 · LAX 09:31 · JFK 12:31
    ♥ Do have faith in what you're doing.