Пожалуйста, объясните, почему скрипт работает таким образом - PullRequest
3 голосов
/ 06 июня 2019

Я работаю в PostgreSQL, и я только начал изучать одновременную работу транзакций. Моя проблема в том, что когда я запускаю весь скрипт, я получаю тот же идентификатор транзакции. Первый кортеж должен иметь 1 идентификатор, а второй 2 - тот же идентификатор.

Когда я запускаю скрипт по строкам (по одной), я получаю правильный результат. Почему так работает?

DELETE FROM test;
INSERT INTO test VALUES (1, 'A');
BEGIN TRANSACTION;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
COMMIT TRANSACTION;

1 Ответ

2 голосов
/ 06 июня 2019

Этот блок кода выполняется в одной транзакции.Вы не сказали, как он выполняется, но если вы вставите его в pgadmin и запустите все вместе, или поместите в файл и вызовете его с помощью psql, транзакция будет автоматически запущена и завершена в конце.Строка BEGIN TRANSACTION не запускает новую транзакцию, потому что транзакция уже открыта.Вот почему выполнение всего этого вместе создаст строки с одинаковыми идентификаторами транзакций.

Чтобы продемонстрировать, запустите эту строку построчно:

BEGIN;
INSERT INTO test VALUES (1, 'A');
SELECT txid_current();
BEGIN TRANSACTION;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
SELECT txid_current();
COMMIT TRANSACTION;

Вы увидите, что каждый SELECT возвращает одно и то жеЯ бы.Вы также увидите сообщение о втором BEGIN, в котором говорится, что транзакция уже выполняется.

Но если вы выделите (в pgadmin) только первый INSERT и выполните его (без выполнения вручнуюBEGIN), это единственная строка, выполняемая в этой автоматической транзакции.Затем остальные выполняются во второй транзакции, независимо от того, выполняете ли вы ее по одной строке за раз или все вместе, потому что транзакция обрабатывается вручную.

Теперь, если вы запустите все эти строки вместе:

BEGIN;
INSERT INTO test VALUES (1, 'A');
COMMIT;
BEGIN;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
COMMIT;

И затем выполните это:

SELECT xmin, *
FROM test

Вы увидите, что номера транзакций соответствуют ожидаемым, поскольку теперь транзакции полностью контролируются вручную - одна создается для первого оператора, а втораядля двух других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...