私が現在持っているロックのフローは、 のSELECT ... FOR UPDATE
後にINSERT
. 例えば
BEGIN;
SELECT count(*) FROM test WHERE col = 1 FOR UPDATE;
# check to ensure an invariant will still be met after the insert.
INSERT INTO test (col) VALUES (1);
COMMIT;
SELECT
上記では、複数の呼び出し元が同時にクリティカル セクションに入るのを防ぐために何かの排他ロックを取得すると予想していましたが、デフォルトでは、InnoDB はテーブルまたはインデックス ギャップの共有ロックのみを取得するようです。2 つの並行トランザクションが同時にこれを試みると、両方が共有ロックを取得できますが、一方は挿入しようとするとデッドロック エラーで失敗します。
同時読み取りを防ぐために、このコードを標準の悲観的ロックのように動作させる方法はありますか?
注: 場合によっては、一意のインデックスでこの問題を解決できることは承知していますが、一意のインデックスが不十分な 2 つのインスタンスに遭遇しました (1) 列の 1 つが null 可能で、正確に 1 つの null 値が必要な場合と (2) ) 特定のキーを持つ行が 10 未満になるように、行に関する別の不変条件を保証したい場合。