V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX  ›  数据库

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

  •  
  •   edis0n0 · 2022-12-02 06:05:04 +08:00 · 4016 次点击
    这是一个创建于 724 天前的主题,其中的信息可能已经有所发展或是发生改变。
    余额变动表有一亿条了,全遍历一遍感觉要很久,有没有效率高的方法?因为这个问题已经出现一天才收到反馈,很多用户在那之后又充值或付款了新订单,不能直接判断最后一次变动金额和当前余额相等。
    23 条回复    2022-12-02 18:59:25 +08:00
    T0m008
        1
    T0m008  
       2022-12-02 06:08:54 +08:00
    第二次扣款没有余额变动记录你怎么在余额变动表里找? mysql 这条路无解。

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