所以我试图找出如何避免竞争条件。 我有一个产品,您可以预订有限的资源。
每个资源都有多个容量。容量是使用名为booking_resources的数据库表中的行数计算的,其中每个预订的资源都有一行。
在代码执行期间,我会执行多项检查,例如:
当"进行预订"预订所需的资源将插入到booking_resources表中。这使得具有resource_id的行数增加,这反过来将使得下一次检查是在给定时间帧中可用的资源。 我的问题是我找不到任何关于在这种情况下做什么的文档。 我应该在资源表中添加一个额外的列,并以这种方式锁定行? (我使用 innodb )
我已经阅读了有关使用select ...进行更新的内容..但这在我的情况下没有意义,因为我不会"缓存"行中的预订数量。 整个想法是我有一个全天候可用的资源,每个预订都需要一些容量。它可能具有10的容量(这意味着我可以有10个人同时使用该资源)。这也意味着(理论上)人们的资源预订可以重叠,只要不超过10人同时使用它。
希望我的问题可以让我了解我面临的问题,并希望你们有一个优雅的解决方案,以防止我的应用程序超量预订。
数据结构:
预定:
id | company_id |点|来自|到|价格| booking_data | booker_choises | due_order_id_datetime(如果不是订单的一部分,则删除预订时)|创建|更新|删除
booking_resources:
id | booking_id | resource_id |来自|到|点|创建|更新|删除
资源:
id | company_id |名字| min_booking | max_bookings | min_points | max_points |创建|更新|删除
为了能够重现这个问题,我在两个不同的窗口中同时点击了同一个按钮。这是通过使用settimeout计时器和单击事件(使用jquery)来完成的。
<script>
function syncClick(selector,time_to_activate){
date = new Date();
if(date.getTime() >= time_to_activate){
console.log('clicked');
jQuery(selector).click();
} else {
setTimeout(function(){
console.log("diff:"+(date.getTime() - time_to_activate));
syncClick(selector,time_to_activate);
},1);
}
}
</script>
感谢。 / W
答案 0 :(得分:-2)
以下案例:
UserA和UserB在星期一检查BookA的可用性。所以它们都会在检查后显示“可用”。使用检查可用性的存储过程“sp_CheckAvail”。它应该在两种情况下都返回true。
现在,UserA请求在星期一预订,所以点击“预订”。这本书将保留给星期一。
请求应如下所示:
call sp_CheckAvail(bookid, $date, available); //This function will check
//wheter the book is available at the moment
of the request
if available
BEGIN
insert into reservations(bookid, date)
values($book, $date); //This will write the reservation only if the book is available
END
select available as result;
对于cource,这必须全部在一个事务中运行,所以即使在同一时刻点击链接,也只有一个客户端会得到预订。
请理解我无法为您撰写完整的查询。但这样就行了。