我正在创建一个模块,其中客户
(所有客户,而非个人)只能在 2 个表中预订同一日期的时间表,最多 5 次,即 Acceptance_bookings
和 turnover_bookings
。
例如,5 位客户预订了同一日期 (07-17-2019) 的行程,其中 3 位为 acceptance_booking
,2 位为 turnover_booking
。如果其他客户尝试在同一日期预订,则应被拒绝。
目前我的实现如下所示:
** START OF TRANSACTION **
** CODE FOR INSERTING ACCEPTANCE OR TURNOVER BOOKING **
$acceptance_bookings = AcceptanceBooking::selectRaw("DATE(date) as date")
->havingRaw("DATE(date) = '$dateString'")
->get()
->count();
$turnover_bookings = TurnoverBooking::selectRaw("DATE(date) as date")
->havingRaw("DATE(date) = '$dateString'")
->get()
->count();
$total_count = $acceptance_bookings + $turnover_bookings;
if($total_count > 5)
** ROLLBACK THE DB TRANSACTION
** END OF TRANSACTION
我担心在竞争条件下,两个插入都有可能通过代码末尾的验证检查,该检查检查截至该日期是否有超过 5 个条目。
在我的实现(上面的代码)中,我在检查预订是否实际上已经超过限制之前插入预订,如果超过 5 个条目则回滚交易。将条件放在插入之前可能会在竞争条件中产生相同的结果。
处理这种情况以避免竞争条件的最佳方法是什么?我想要维持的严格要求是,2 个表中相同预订时间表的条目不得超过 5 个。
注意:我无法更改表格,例如尝试创建预订表并使用引用 ID 来确定它是接受预订还是周转预订,因为我正在集成一个已经运行的系统。
最佳答案
你的代码有正确的想法;问题是什么? BEGIN
在开始,COMMIT
在结束(如果没有失败)。
还有一件事:SELECT
需要是 SELECT .. FOR UPDATE
。这会“锁定”您正在计数的行 --> 避免竞争问题。
关于php - 如何只插入相同日期的条目不超过4条?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57540723/