SELECT
및 가능한 INSERT
인 트랜잭션이 있습니다. 동시성을 이유로 SELECT
에 FOR UPDATE
을 추가했습니다. 유령 행을 방지하기 위해 나는 SERIALIZABLE
트랜잭션 격리 수준을 사용하고 있습니다. 이 테이블에 행이있을 때이 모든 작동합니다, 있지만 테이블이 비어 있지 않은 경우. 테이블이 비어있는 경우 SELECT FOR UPDATE
은 (단독적인) 잠금을 수행하지 않으며 동시 스레드/프로세스는 잠겨 있지 않고 동일한 SELECT FOR UPDATE
을 발행 할 수 있습니다.innodb 및 serializable 트랜잭션을 사용하는 Mysql은 항상 행을 잠그지 않습니다
CREATE TABLE t (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
display_order INT
) ENGINE = InnoDB;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT COALESCE(MAX(display_order), 0) + 1 from t FOR UPDATE;
..
이 개념은 SQL Server에서는 예상대로 작동하지만 MySQL에서는 예상대로 작동합니다. 내가 뭘 잘못하고 있는지에 대한 아이디어가 있습니까?
편집
display_order에 인덱스를 추가하면 동작을 변경하지 않습니다. http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
당신이 저를 요구하는 경우에, mysql을가 구축되지 않은이 내 권고가은 ... 그런 식으로 사용되는 :
더보기 5.1 문서, 격리 수준 관리가 지금은 전혀 다릅니다 – regilero
MySQL의 문서는 명시 적으로 이러한 경우에 대한 이해를 사용하여 FOR UPDATE를 사용하는 것이 좋습니다. 빈 테이블과 의미가 다른 것처럼 보입니다. –