我有一个API端点,通过身份验证的用户可以使用它来预订活动。一旦对API的预订调用成功,该数量的位置就会被“消耗”,无法由其他用户预订。
我试图实现的是组织并发调用,以***避免***出现以下情况:
- 会场有10个名额
- 用户A进行API调用以预留6个位置
- 用户B在大约相同的时间(毫秒之后)进行API调用以预留5个位置
- 在来自用户A的呼叫完成并锁定6个位置之前,来自用户B的呼叫继续进行,好像它将成功一样,因为它看到10个位置可用。
基本上,我是在尝试按顺序组织我的电话。
关于进一步考虑:
- 我正在使用Microsoft Azure -我是否应该考虑使用排序队列?
- 我还使用EF核心为我的后端数据,如果这可以使不同的方式,我不能想到。
- 有没有一个库可以用来实现这种类似信号量的方法?
我完全理解,在作为一个替代方案,我可以软保留一个点,在一个时间为每个用户,只有当所有的点得到软保留成功,我然后继续和硬保留他们.在我走一些路线像这样一个,我很好奇,如果有一些不那么笨拙的方法.
谢谢
2条答案
按热度按时间y0u0uwnf1#
如果你同意在数据库级别使用悲观锁,你可以不用队列或异步来解决这个问题。悲观锁本质上是一种序列化的方法。我不推荐使用进程内锁,比如
lock
关键字/互斥锁等等。现代的API有多个示例,所以排除了单机/内存互斥锁。您可以立即(同步)调用某种类型的持久存储(例如,专用于预留插槽的表)来预留
M
插槽。这可能类似于"update the record whereNAvailable - M >= 0
"。"该记录"将通过一些标准(例如房间ID)来标识。POST
返回201 CREATED(它是POST
,因为您要求创建一个保留)。这必然会更加复杂,但可能会增加解决方案的并发性。在这种情况下,您通常会接受来自客户端的所有调用,并将它们排入队列。同样,您可以使用
ConcurrentQueue
等内存中解决方案来序列化请求,但最好使用使用Azure队列等"真正"排队机制的分布式解决方案。在这个场景中,每个客户端请求都会立即被放到队列中,API返回一个202 ACCEPTED,队列的使用者尝试完成请求,整个工作流将遵循Asynchronous Request-Reply pattern。
这需要在服务器(跟踪工作和实现)和客户机(轮询以确定工作是否真正成功,或者响应SignalR的推送通知)上进行更多的工作。
我正在使用Microsoft Azure-我是否应该考虑使用排序队列?
是的。这是合理的,而且从并发的Angular 来看更为乐观。使用"软保留"扩展了这种方法,不仅合理,而且很常见;考虑在飞机上预订座位。您可以在很短的时间内获得座位,但不会永远获得。工作流更加复杂,但如果乐观并发失败,则允许使用compensating transactions。
我还使用EF核心为我的后端数据,如果这可以使不同的方式,我不能想到。
我不认为这会有什么不同。这是对数据库的抽象。
有没有一个库可以用来实现这种类似信号量的方法?
也许吧,大多数都属于模式领域,这意味着您可能可以使用一些样板代码(我知道我已经这样做过几次了!)或一个编码模式的框架。
gcuhipw92#
这是多线程系统中的一个常见问题。有很多方法可以解决这个问题,但如果调用速度快,负载不是很大,你可能可以用ReaderWriterLockSlim这样的东西来解决。我不太精通Azure,但如果我自己编写服务器,这将是我快速而肮脏的解决方案。