【发布时间】:2019-12-23 17:28:15
【问题描述】:
我正在创建一个模块,其中customers(所有客户,而不是个人)应该只能在 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 个条目则回滚交易。将条件放在插入之前可能会在竞争条件中产生相同的结果。
处理这种情况以避免竞争条件的最佳方法是什么?我要保持的严格要求是,两张桌子上的相同预订时间表的条目不得超过 5 个。
注意:我无法更改表格,例如尝试创建预订表格并使用参考 ID 来确定它是接受预订还是营业额预订,因为我正在集成一个已经工作的系统。
【问题讨论】:
-
请参阅Why should I provide a Minimal Reproducible Example for a very simple SQL query? 以获取示例数据和预期结果。我们需要知道问题/查询中涉及的每个表的表看起来像
SHOW CREATE TABLE table,我们需要知道数据的外观喜欢。 -
但也许像
INSERT INTO <columns> SELECT <columns> FROM DUAL WHERE 5 <= (SELECT COUNT(*) FROM table WHERE DATE(date) = '<some_date>')之类的? edit: 如果你需要检查两个表,你也可以合并它.. -
感谢您的建议,我会研究一下
标签: php mysql laravel validation query-optimization