2016-07-21 3 views
1

예약 시스템을 만들 예정입니다. 이 시스템에는 한정된 시간 내에 사람을 만날 수있는 능력이 제한적인 사람이 있습니다. 예 : 사람 A는 일요일 8 시부 터 12시 사이에 최대 8 명과 회의를 가질 수 있습니다.mySQL 데이터베이스 삽입의 동시성을 처리하기위한 논리적 제약 사항 관리

내 데이터베이스에는 다음과 같은 두 개의 테이블이 있습니다. Timings에는 미리 정의 된 일정이 표시되고 Bookings에는 고정 된 예약이 표시됩니다. 이 표는 다음과 같이 정의된다 : 나는 새 모임을 예약 할거야 때 지정된 타이밍에 관한 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 ; 

그래서, 내가 확인해야 예약.

이것은 필수 조건이지만 동시성이 발생하는 경우에는 충분하지 않습니다. 내가 마지막으로 사용할 수있는 예약에 대해 count of (timings where timingFK=XXX)< timing.capacity을 확인하면 두 사람이 동시에 예약 할 수있는 상황이 발생할 수 있습니다. 그 이유는 언제 마지막 예약을 사용할 수 있는지 조건을 확인할 수 있기 때문입니다. 나는 새로운 예약을 삽입하는 동안 두 사람이 마지막 왼쪽 위치를 예약하지 않도록 세마포어 같은 것을 어떻게 구현할 수 있는지 알고 싶습니다.

답변

0

최대의 안전을 위해 거래 + select for update을 사용하십시오. 인덱스

는 당신이 그 행에 대한 UPDATE 문을 발행 것처럼 UPDATE 잠금 행과 연관된 인덱스 항목, 같은 SELECT ... FOR 검색 만남을 기록합니다. 다른 트랜잭션은 이 SELECT ... LOCK IN SHARE MODE에서 해당 행을 업데이트하지 못하도록 차단하거나 에서 특정 트랜잭션 격리 수준의 데이터를 읽을 수 없습니다. 일관된 읽기는 읽기보기에있는 레코드에 설정된 모든 잠금을 무시합니다. (기록의 이전 버전은 고정 될 수 없다. 그들은 기록의 메모리 복사에 로그를 취소 적용하여 재구성 이다) 당신이있을

그래서

START TRANSACTION; 
SELECT COUNT(*) FROM Bookings WHERE somecondition FOR UPDATE 
INSERT INTO timings ... 
UPDATE Bookings .... 
COMMIT;