Операції в рамках транзакції


18

Яка поведінка відображатиметься PostgreSQL, якби, наприклад, був названий сценарій нижче

BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;

Чи відкине PostgreSQL друге, BEGINчи буде прийнято неявне рішення, а потім виконати BEGIN ENDблок в кінці як окрему транзакцію?

Відповіді:


13

Вам знадобиться так звана "автономна транзакція" (функція, що надається Oracle). Наразі це неможливо в PostgreSQL. Однак ви можете використовувати SAVEPOINT s:

BEGIN;
INSERT ...
SAVEPOINT a;
some error;
ROLLBACK TO SAVEPOINT a;
COMMIT;

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

Інакше на даний момент немає іншого розумного рішення.


13

Ви можете спробувати самостійно:

ПОПЕРЕДЖЕННЯ: вже здійснена транзакція

Він не запускає нових (під) транзакцій, оскільки вкладені транзакції не реалізовані в PostgreSQL. (Ви можете зробити якусь магію у pl/pgsqlфункції, наприклад, яка імітує таку поведінку.)

З PostgreSQL 11 можна було б подумати, що нові реальні збережені процедури та їх здатність обробляти транзакції дозволять зробити вкладені транзакції можливими. Однак, згідно з документацією , це не так:

У процедурах, які викликаються CALLкомандою, а також в анонімних кодових блоках ( DOкоманда), можна закінчити транзакції за допомогою команд COMMITі ROLLBACK. Нова транзакція починається автоматично після завершення транзакції за допомогою цих команд, тому окремої команди START TRANSACTION немає.


9

PostgreSQL не підтримує суб-транзакції, але ця SAVEPOINTфункція може ефективно відповідати вашим потребам. Цитування з документації Advanced шару доступу до PG через обіцянки по Віталію Томілова на GitHub:

PostgreSQL не має належної підтримки вкладених транзакцій, він підтримує лише часткові зворотні звороти через точки збереження всередині транзакцій. Різниця між двома методиками величезна, як пояснено далі.

Належна підтримка вкладених транзакцій означає, що результат вдалої транзакції не повертається назад, коли його батьківська транзакція повертається назад. Але з PostgreSQL точками збереження, якщо ви відкатуєте транзакцію верхнього рівня, результат усіх внутрішніх точок збереження також відкочується.

Точки збереження можуть використовуватися для часткових відкотів до попередньої точки всередині активної транзакції. Наприклад, щоб встановити точку збереження та пізніше скасувати ефекти всіх команд, виконаних після її встановлення:

BEGIN;
    INSERT INTO table1 VALUES (1);
    SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (2);
    ROLLBACK TO SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (3);
COMMIT;

У вищевказаній транзакції будуть вставлені значення 1 і 3, але не 2. Дивіться SAVEPOINTдокументацію для отримання додаткової інформації.


0

Для Postgresql 9.5 або новіших ви можете використовувати динамічні фонові робітники, передбачені розширенням pg_background. Це створює автономну транзакцію. Будь ласка, зверніться до сторінці GitHub розширення. Забруднення краще, ніж db_link. Існує повний посібник з підтримки автономних транзакцій у PostgreSQL

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.