我想这是一个经典的并发问题。
我有人报名参加活动。该活动可以处理最多的参与者。
这是一个带有PostgreSQL数据库的Symfony应用程序。
确保活动不会超额预订的最佳方法是什么?
假设我有一些名为Event,Person和Booking的实体。预订与人和事件有一对多的关系。
我显示有关该事件的页面。如果计数小于最大值,我会计算当前预订并显示“立即预订”按钮
以下是我之前完成此操作的一些伪代码:
关于立即预订按钮的操作:
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
ENDIF
我认为这种方法既安全又不理想。我认为当剩下一个空格并且两个都被拒绝时,可能会导致两个人预订。现实世界发生这种情况的几率可能接近于零,我想用户会再试一次但是......这样做会很好。
有更好的方法吗?
我读过这个:Handling the concurrent request while persisting in oracle database?和几个月前我问过的类似问题。当最大预订= 1(如航空公司座位)时,乐观锁定似乎是一个很好的策略。在那种情况下,我可能根本就没有预订实体。事件只会有一个人。
答案 0 :(得分:0)
查看学说文档Concurrency and Transactions,您可以使用一些选项。
我同意乐观锁定可能是要走的路,但你不必改变你当前的逻辑。只需向要插入的实体添加一个新的version
字段(类型serial
是最好的),当您执行初始SELECT时,您将传入唯一的版本号。然后,当您插入时,如果版本已更改,您知道其他人已经预订并且插入不会发生。
更新
更新实体时,乐观锁定将起作用。对于插入新实体,交易将是最好的选择。