我想这是一道经典的并发题。
有人报名参加事件。该事件可以容纳最大数量的参与者。
这是一个带有 PostgreSQL 数据库的 Symfony 应用程序。
确保事件不会超额预订的最佳方法是什么?
假设我有名为 Event、Person 和 Booking 的实体。 Booking 与 Person 和 Event 具有一对多关系。
我显示一个关于事件的页面。我计算当前的预订,如果计数小于最大值,则显示“立即预订”按钮。
这是我之前如何完成此操作的一些伪代码:
关于“立即预订”按钮的操作:
Count bookings
if count >= max
return "Sorry, this event is full"
else
Create booking
Flush entity manager
Count bookings again
if count > max
Delete booking
return "Sorry, this event is full"
endif
结束
我认为这种方法是安全的,但并不理想。我认为这可能会导致两个人在剩下一个空间时预订,但都被拒绝了。发生这种情况的真实可能性可能接近于零,我想用户会再试一次,但是......正确地做到这一点会很好。
有更好的方法吗?
我读过这个:Handling the concurrent request while persisting in oracle database?以及几个月前我问过的一个类似问题。当最大预订量 = 1 时(例如飞机座位),乐观锁定似乎是一个很好的策略。在那种情况下,我可能根本不会有 Booking 实体。事件将只有一个人或没有。
最佳答案
看看学说文档 Concurrency and Transactions , 您可以使用几个选项。
我同意乐观锁定可能是可行的方法,但您不必更改当前的逻辑。只需向要插入的实体添加一个新的 version
字段(类型 serial
最好),当您执行初始 SELECT 时,您传入唯一的版本号.然后插入的时候,如果版本变了,就知道别人已经预定了,插入就不会发生了。
文档中有一些很好的例子 Optimistic Locking
更新
乐观锁定将在更新实体时起作用。对于插入新实体,交易将是最好的选择。
关于postgresql - 人们预订事件,如何正确限制最大预订数量? (并发),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22150920/