我目前拥有的锁定流程是 aSELECT ... 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 只在表或索引间隙上获得一个共享锁。如果两个并发事务同时尝试此操作,它们都可以获得共享锁,但在尝试插入时会失败并出现死锁错误。
有没有办法让这段代码表现得更像标准的悲观锁定来防止并发读者?
注意:我知道在某些情况下,唯一索引可以解决此问题,但我遇到了两个实例,其中唯一索引不足 (1) 当其中一列可以为空并且我只想要一个空值和 (2 ) 当我想保证行的另一个不变性时,例如给定键的行应该少于 10 行。