大佬们,一般支付系统,涉及到账户并发,使用哪种技术解决?我们目前调研了乐观锁以及基于 redisson 的公平锁。设计公平锁的老哥,把问题整的挺复杂,还考虑到多台服务器宕机,维护了自己的心跳机制;乐观锁的,基于时间戳来控制并发,有一定的重试机制。
1
rapperx2 2023-03-20 11:28:22 +08:00
2 楼会,坐等二楼大佬解答
|
2
MoYi123 2023-03-20 11:32:51 +08:00
支付系统不是只要照抄支付宝 /微信的文档里写的做法就行了吗? 好像也不怎么要用到锁吧.
|
3
ALLROBOT 2023-03-20 11:34:15 +08:00
ChatGPT 来解答了,它是全世界最会的,ai:
在支付系统中涉及到账户并发时,常用的技术包括分布式锁和分布式事务。分布式锁可以通过乐观锁、悲观锁或者基于 Redis 等技术实现。而分布式事务可以通过基于 XA 协议的两阶段提交或者 TCC ( Try-Confirm/Cancel )等技术来解决。 对于公平锁与乐观锁的选择,需要根据具体情况进行权衡。公平锁相对复杂,但能够保证请求的公平性;乐观锁简单易用,但需要考虑重试机制。同时,对于多台服务器宕机的情况,可以通过引入高可用技术如心跳机制、集群等方式来提高系统的可靠性和容错性。 |
5
dqzcwxb 2023-03-20 11:41:12 +08:00 2
设计支付的不要使用乐观锁,甚至在确定存在并发的业务上都不要使用乐观锁,重试和回滚会让整个业务更复杂
支付系统中小型项目用个 redis 分布式锁(悲观锁)按 uid 上锁即可,大了再考虑队列,多队列单消费者等等方案不过到那时候大概率也跟你没啥关系了 解决并发的方案就那么几种,单线程消费,分布式锁,队列 而且你仔细研究下会发现它们本质上都是一种解决方案:并行改串行 |
7
wu00 2023-03-20 12:01:46 +08:00
小项目乐观锁+本地消息表+回调通知,基本上借用数据库的稳定性来保证业务,简单&安全。
乐观锁可以封装在数据库操作层,分布式锁一般在业务代码层,用分布式锁很容易在代码层面出现多个需要操作余额的业务用的不是同一把锁。 |
8
q1angch0u 2023-03-20 12:09:02 +08:00
2pc
|
9
git00ll 2023-03-20 12:21:27 +08:00 1
别用 redis 分布式锁,redis 不稳的
用数据库 for update , 除了性能稍差点。其他一点问题没有 |
10
opengps 2023-03-20 12:35:54 +08:00
我觉得支付系统并发最小,一个人没发同一刻同时对外转账
|
11
smartxia OP 感谢各位大佬回复。我们讨论了 2 种方案,觉得 redis 的公平锁实现比较复杂,怕以后纠错追溯麻烦;乐观锁的,要考虑到重试时同一个事务读取的还是旧值,所以改了隔离级别,实现上比 redis 公平锁简单点,可能需要开发尽量缩小事务代码
|
14
smartxia OP 这个系统有个中央仓库的概念,用户的钱都是来自这个仓库的,存在多个管理员并发操作的问题;给多个用户发钱的时候,有可能业务没处理完,有其他管理员操作导致余额不一致吧
|
15
ymmud 2023-03-20 13:30:31 +08:00
可以用类似 akka 的分片,单账户串行
|
16
dayeye2006199 2023-03-20 14:03:31 +08:00
流量不太大,建议数据库自己带的锁机制+事务就可以解决了
|
17
yogogo 2023-03-20 15:15:16 +08:00
要看你公司有没有多大体量的交易额,单台数据库带的锁机制+事务一天几千万流水稳稳单单
|
18
liudaolunhuibl 2023-03-20 15:26:42 +08:00
@git00ll 你说 redis 分布锁不可靠吧那应该用 zk 啊,怎么推荐数据库的 for update 了
|
19
kkk1234567 2023-03-20 16:27:28 +08:00
@smartxia 小成本的话,可以考虑给你的中央仓库弄成 10 个, 比如 10 个管理员 各自给 100 个用户发钱,别发重复就好。
|
20
smartxia OP @kkk1234567 用户之间也有资金来往,此时管理员也有可能在发钱,所以这种方案不太好弄;我们这个给用户分组了,有可能同一个用户在不同组。
|
21
INCerry 2023-03-21 09:59:03 +08:00
可以看看 Virtual Actor 模型,业内很多都是用这个来解决
|