Пытаясь поддерживать базу данных PostgreSQL в моем приложении, я обнаружил странное поведение.
Подготовка:
CREATE TABLE test(id INTEGER, flag BOOLEAN);
INSERT INTO test(id, flag) VALUES (1, true);
Предположим, что две одновременные транзакции (Autocommit = false, READ_COMMITTED) TX1 и TX2:
TX1:
UPDATE test SET flag = FALSE WHERE id = 1;
INSERT INTO test(id, flag) VALUES (2, TRUE);
-- (wait, no COMMIT yet)
TX2:
SELECT id FROM test WHERE flag=true FOR UPDATE;
-- waits for TX1 to release lock
Теперь, если я COMMIT в TX1, SELECT в TX2 вернет пустой курсор.
Мне это странно, потому что один и тот же эксперимент в Oracle и MariaDB приводит к выбору вновь созданной строки (id = 2).
Я не смог найти ничего об этом в документации PG. Я что-то упускаю? Есть ли способ заставить PG-сервер «обновить» видимость оператора после получения блокировки?
PS: PostgreSQL версии 11.1