私はSELECT
と可能なINSERT
のトランザクションを持っています。並行性の理由から、私はSELECT
にFOR UPDATE
を追加しました。ファントム行を防ぐために、私はSERIALIZABLE
トランザクション分離レベルを使用しています。これはテーブル内に行がある場合はすべて正常に動作しますが、の場合はではありません。テーブルが空の場合、SELECT FOR UPDATE
は(排他的な)ロックを行わず、同時のスレッド/プロセスはロックされずに同じSELECT FOR UPDATE
を発行することができます。innodbとシリアライズ可能なトランザクションを使用した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では期待されません。私が間違っていることに関するアイデアは?
EDIT
display_orderにインデックスを追加すると、動作を変更しません。
優れた外観を5.1ドキュメントでは、分離レベルの管理が今では全く異なっています – regilero
Mysqlのドキュメントでは、わかっているので、これらのケースに対してFOR UPDATEを使用することが明示的に推奨されています。セマンティクスが空のテーブルと異なるように見えるだけです。 –