我要创建一个预订系统。在该系统中,有一些人在规定的时间段内与人会面的能力有限。例如。 A人可于周日8:00至12:00之间与最多8人会面。
在我的数据库中,我有两个表格:Timings
显示预定义的时间表,Bookings
显示已修复的预订。
这些表定义如下:
CREATE TABLE IF NOT EXISTS `Timings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`day` varchar(100) COLLATE utf8_persian_ci NOT NULL,
`start_time` int(11) NOT NULL,
`end_time` int(11) NOT NULL,
`capacity` int(11) NOT NULL,
`personFK` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_person_timing` (`personFK`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=12 ;
CREATE TABLE IF NOT EXISTS `Bookings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(100) COLLATE utf8_persian_ci NOT NULL,
`order` int(11) NOT NULL,
`booking_code` varchar(100) COLLATE utf8_persian_ci NOT NULL,
`timingFK` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_booking_timing` (`timingFK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=1 ;
因此,当我要预订新会议时,我应该检查Bookings
表中与指定时间相关的行数是否小于允许新预订的容量。
这是一个必要条件,但在并发发生时还不够。
我的意思是,如果我检查count of (timings where timingFK=XXX)< timing.capacity
,对于最后一次预订,可能会有两个人被允许同时预订,因为当他们检查条件时,最后一次预订仍然可用。我想知道如何实现信号量类似的东西,以避免两个人在插入新预订时预订最后左侧位置?
答案 0 :(得分:0)
为了最大限度地提高安全性,请使用交易+ select for update。
对于搜索遇到的索引记录,SELECT ... FOR UPDATE锁 行和任何关联的索引条目,与您发出的相同 这些行的UPDATE语句。其他交易被阻止 从更新那些行,进行SELECT ... LOCK IN SHARE MODE,或 从某些事务隔离级别读取数据。 一致性读取将忽略对存在的记录设置的任何锁定 阅读视图。 (旧版本的记录无法锁定;它们是 通过在内存中的副本上应用撤消日志来重建 记录。)
所以你可能有
START TRANSACTION;
SELECT COUNT(*) FROM Bookings WHERE somecondition FOR UPDATE
INSERT INTO timings ...
UPDATE Bookings ....
COMMIT;