Я внимательно читал документацию postgres по изоляции транзакций, предложенную в других моих вопросах, но мне еще не удалось понять, что такое "предикатная блокировка".
Надеюсь, кто-нибудь может просветить меня: -)
В соответствии с документацией: блокировки Predicate в PostgreSQL, как и в большинстве других систем баз данных, основаны на данных, фактически доступных транзакцией
Это звучит хорошо, тогда почему происходит следующее?
CREATE TABLE mycustomer(cid integer PRIMARY KEY, licenses integer);
CREATE TABLE mydevice(id integer PRIMARY KEY, cid integer REFERENCES
mycustomer (cid), status varchar(10));
INSERT INTO mycustomer(cid, licenses) VALUES (1, 5);
INSERT INTO mycustomer(cid, licenses) VALUES (2, 5);
Request 1 Request2
BEGIN TRANSACTION ISOLATION
LEVEL SERIALIZABLE;
BEGIN TRANSACTION ISOLATION
LEVEL SERIALIZABLE;
SELECT * from mydevice where cid = 1;
SELECT * from mydevice where cid = 2;
INSERT INTO mydevice(id, cid, status)
VALUES (1, 1, 'ok');
INSERT INTO mydevice(id, cid, status)
VALUES (2, 2, 'ok');
commit;
(=ok)
commit;
(=rollback)
Я понимаю, что вставки из запроса 1 и запроса 2 не противоречат предыдущим чтениям и, следовательно, не должно быть никаких ошибок. Почему я получаю сообщение "ОШИБКА: невозможно выполнить сериализацию доступа из-за зависимостей чтения/записи между транзакциями".
Как вы можете себе представить, я не могу иметь вышеупомянутое поведение, так как каждый параллельный запрос будет откатываться независимо от его деталей. В моем бизнес-сценарии я хотел бы, чтобы одновременные запросы выполнялись только при резервном копировании, когда они вставляли данные (в соответствии с примерами устройств) для одного и того же клиента.
Эти операции выполняются из приложения Java. В принципе я думаю о создании таблицы блокировки для удовлетворения моих потребностей. Любые идеи?
Большое спасибо!