预订活动的人,如何正确限制预订的最大数量? (并发)

时间:2014-03-03 15:39:29

标签: postgresql symfony concurrency

我想这是一个经典的并发问题。

我有人报名参加活动。该活动可以处理最多的参与者。

这是一个带有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(如航空公司座位)时,乐观锁定似乎是一个很好的策略。在那种情况下,我可能根本就没有预订实体。事件只会有一个人。

1 个答案:

答案 0 :(得分:0)

查看学说文档Concurrency and Transactions,您可以使用一些选项。

我同意乐观锁定可能是要走的路,但你不必改变你当前的逻辑。只需向要插入的实体添加一个新的version字段(类型serial是最好的),当您执行初始SELECT时,您将传入唯一的版本号。然后,当您插入时,如果版本已更改,您知道其他人已经预订并且插入不会发生。

文档在Optimistic Locking

中有一些很好的例子

更新

更新实体时,乐观锁定将起作用。对于插入新实体,交易将是最好的选择。