屎山代码导致一部分用户付款后被扣除了两次余额,第二次扣款是没有创建余额变动记录的, mysql 如何快速找出这部分余额异常的用户? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX    数据库

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

  •  
  •   edis0n0 2022-12-02 06:05:04 +08:00 4381 次点击
    这是一个创建于 1044 天前的主题,其中的信息可能已经有所发展或是发生改变。
    余额变动表有一亿条了,全遍历一遍感觉要很久,有没有效率高的方法?因为这个问题已经出现一天才收到反馈,很多用户在那之后又充值或付款了新订单,不能直接判断最后一次变动金额和当前余额相等。
    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 是说钱多扣了,但是扣款记录没有,余额已经少了
    Glkcv
        8
    Glkcv  
       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  
      &nbs;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     Solana     2651 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 13:45 PVG 21:45 LAX 06:45 JFK 09:45
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86