PostgreSQL 的 pg_try_advisory_xact_lock 正确使用姿势是什么

2021-07-04 14:37:03 +08:00
 dzdh

看到 pg_try_advisory_xact_lock (咨询锁)可以事务中免等待

实际场景是啥?

看很多描述是秒杀场景,那就拿秒杀来说,,一件商品,多人下单,那就是多个事物,只有一个人能下单(扣减库存)成功。

然后没拿到锁的呢?直接前端抛出个抢购失败的异常?然后刷新页面一看还有库存?业务代码逻辑自动重试?重试多少次呢?

因为很多场景其实并不都是极限秒杀场景(成百上千人抢),可能就是平常的一个商品,某个店铺搞了个活动(平台也不晓得)突然就大流量上来了。

就是不固定不定时毫无预兆的普通商品抢购,自动重试次数少了,刷新页面看还有库存。自动重试次数多了,那还不如事物里锁这条数据呢。

更具体的使用场景或姿势是啥?

1556 次点击
所在节点    PostgreSQL
6 条回复
liprais
2021-07-04 15:25:50 +08:00
dzdh
2021-07-04 23:05:52 +08:00
@liprais 就是看了这个。业务中如何实现呢。

非秒杀,两个用户同时请求,一个成功,另一个告知稍后重试?还是抛个异常说库存不足了?没拿到锁的在业务代码中自动重试?重试多少次呢?重试 3 次?那抢购场景重试三次后告知人太多刷新页面一看库存依然充足,再下单依然提示抢购人数太多?这体验并不觉得多好鸭。
oclock
2021-07-05 09:12:56 +08:00
好几年不写后端,胡扯一句:“自动重试”通常是糟糕的设计
dzdh
2021-07-05 09:24:16 +08:00
@oclock 那这玩意儿存在的意义是啥,单纯保证同一时间能直接“取得”这条数据是否被锁的结果?那为何说适合秒杀呢
MoYi123
2021-07-05 09:30:05 +08:00
个人观点不一定对。
这个锁在并发量小的时候,基本上是必定成功,在并发量大的时候,成功率也不低。
一般来说,秒杀场景没有那么多的库存,如果参与的人多,那么再次刷新页面的时候,库存一定没了,如果人少,那就不会拿不到锁。
dzdh
2021-07-05 10:05:54 +08:00
@MoYi123

>这个锁在并发量小的时候,基本上是必定成功,在并发量大的时候,成功率也不低。

如,就两个并发,同一时间事务进来,必定有一个人拿不到锁然后就 GG 了?

测试方法:就两个人同时点提交按钮。(查是否有重复订单、是否被限购、商品是否在售、用户是否登录、更新用户在线状态等等等巴啦啦)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/787443

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX