管理逻辑约束以处理mySQL数据库插入中的并发性

时间:2016-07-21 05:04:54

标签: mysql concurrency semaphore sql-insert

我要创建一个预订系统。在该系统中,有一些人在规定的时间段内与人会面的能力有限。例如。 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,对于最后一次预订,可能会有两个人被允许同时预订,因为当他们检查条件时,最后一次预订仍然可用。我想知道如何实现信号量类似的东西,以避免两个人在插入新预订时预订最后左侧位置?

1 个答案:

答案 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;