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

支付系统的并发处理方式

  •  
  •   smartxia · 2023-03-20 11:24:55 +08:00 · 3632 次点击
    这是一个创建于 625 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大佬们,一般支付系统,涉及到账户并发,使用哪种技术解决?我们目前调研了乐观锁以及基于 redisson 的公平锁。设计公平锁的老哥,把问题整的挺复杂,还考虑到多台服务器宕机,维护了自己的心跳机制;乐观锁的,基于时间戳来控制并发,有一定的重试机制。

    21 条回复    2023-03-21 09:59:03 +08:00
    rapperx2
        1
    rapperx2  
       2023-03-20 11:28:22 +08:00
    2 楼会,坐等二楼大佬解答
    MoYi123
        2
    MoYi123  
       2023-03-20 11:32:51 +08:00
    支付系统不是只要照抄支付宝 /微信的文档里写的做法就行了吗? 好像也不怎么要用到锁吧.
    ALLROBOT
        3
    ALLROBOT  
       2023-03-20 11:34:15 +08:00
    ChatGPT 来解答了,它是全世界最会的,ai:

    在支付系统中涉及到账户并发时,常用的技术包括分布式锁和分布式事务。分布式锁可以通过乐观锁、悲观锁或者基于 Redis 等技术实现。而分布式事务可以通过基于 XA 协议的两阶段提交或者 TCC ( Try-Confirm/Cancel )等技术来解决。

    对于公平锁与乐观锁的选择,需要根据具体情况进行权衡。公平锁相对复杂,但能够保证请求的公平性;乐观锁简单易用,但需要考虑重试机制。同时,对于多台服务器宕机的情况,可以通过引入高可用技术如心跳机制、集群等方式来提高系统的可靠性和容错性。
    beckyho
        4
    beckyho  
       2023-03-20 11:35:46 +08:00
    @MoYi123 你说的是对接第三方;楼主的意思是自己公司的支付系统
    dqzcwxb
        5
    dqzcwxb  
       2023-03-20 11:41:12 +08:00   ❤️ 2
    设计支付的不要使用乐观锁,甚至在确定存在并发的业务上都不要使用乐观锁,重试和回滚会让整个业务更复杂
    支付系统中小型项目用个 redis 分布式锁(悲观锁)按 uid 上锁即可,大了再考虑队列,多队列单消费者等等方案不过到那时候大概率也跟你没啥关系了
    解决并发的方案就那么几种,单线程消费,分布式锁,队列 而且你仔细研究下会发现它们本质上都是一种解决方案:并行改串行
    SWBMESSI
        6
    SWBMESSI  
       2023-03-20 11:47:49 +08:00
    @ALLROBOT AI 回答会被 ban 的
    wu00
        7
    wu00  
       2023-03-20 12:01:46 +08:00
    小项目乐观锁+本地消息表+回调通知,基本上借用数据库的稳定性来保证业务,简单&安全。
    乐观锁可以封装在数据库操作层,分布式锁一般在业务代码层,用分布式锁很容易在代码层面出现多个需要操作余额的业务用的不是同一把锁。
    q1angch0u
        8
    q1angch0u  
       2023-03-20 12:09:02 +08:00
    2pc
    git00ll
        9
    git00ll  
       2023-03-20 12:21:27 +08:00   ❤️ 1
    别用 redis 分布式锁,redis 不稳的
    用数据库 for update , 除了性能稍差点。其他一点问题没有
    opengps
        10
    opengps  
       2023-03-20 12:35:54 +08:00
    我觉得支付系统并发最小,一个人没发同一刻同时对外转账
    smartxia
        11
    smartxia  
    OP
       2023-03-20 12:36:03 +08:00
    感谢各位大佬回复。我们讨论了 2 种方案,觉得 redis 的公平锁实现比较复杂,怕以后纠错追溯麻烦;乐观锁的,要考虑到重试时同一个事务读取的还是旧值,所以改了隔离级别,实现上比 redis 公平锁简单点,可能需要开发尽量缩小事务代码
    Livid
        12
    Livid  
    MOD
       2023-03-20 12:37:49 +08:00   ❤️ 2
    @ALLROBOT 请不要再把用 AI 生成的回复发送到这里。
    neochen13
        13
    neochen13  
       2023-03-20 12:39:11 +08:00   ❤️ 1
    管理员好,3 楼是 AI 回答
    @Livid
    smartxia
        14
    smartxia  
    OP
       2023-03-20 12:39:31 +08:00
    这个系统有个中央仓库的概念,用户的钱都是来自这个仓库的,存在多个管理员并发操作的问题;给多个用户发钱的时候,有可能业务没处理完,有其他管理员操作导致余额不一致吧
    ymmud
        15
    ymmud  
       2023-03-20 13:30:31 +08:00
    可以用类似 akka 的分片,单账户串行
    dayeye2006199
        16
    dayeye2006199  
       2023-03-20 14:03:31 +08:00
    流量不太大,建议数据库自己带的锁机制+事务就可以解决了
    yogogo
        17
    yogogo  
       2023-03-20 15:15:16 +08:00
    要看你公司有没有多大体量的交易额,单台数据库带的锁机制+事务一天几千万流水稳稳单单
    liudaolunhuibl
        18
    liudaolunhuibl  
       2023-03-20 15:26:42 +08:00
    @git00ll 你说 redis 分布锁不可靠吧那应该用 zk 啊,怎么推荐数据库的 for update 了
    kkk1234567
        19
    kkk1234567  
       2023-03-20 16:27:28 +08:00
    @smartxia 小成本的话,可以考虑给你的中央仓库弄成 10 个, 比如 10 个管理员 各自给 100 个用户发钱,别发重复就好。
    smartxia
        20
    smartxia  
    OP
       2023-03-20 16:39:46 +08:00
    @kkk1234567 用户之间也有资金来往,此时管理员也有可能在发钱,所以这种方案不太好弄;我们这个给用户分组了,有可能同一个用户在不同组。
    INCerry
        21
    INCerry  
       2023-03-21 09:59:03 +08:00
    可以看看 Virtual Actor 模型,业内很多都是用这个来解决
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1003 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:20 · PVG 05:20 · LAX 13:20 · JFK 16:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.