Postgresql - восстановление в точку сохранения через границы транзакции - PullRequest
0 голосов
/ 09 апреля 2020

Есть ли способ откатиться до «зафиксированной точки сохранения»?

Afaik, фактические точки сохранения, поддерживаемые postgresql, являются субтранзакциями и теряют свое значение, когда транзакция вложения фиксируется или прерывается. Существуют ли «точки сохранения» через границы транзакции?

По сути, я хочу выполнить эти три транзакции в следующем порядке:

Транзакция ~ A

BEGIN TRANSACTION;
    COMMIT SAVEPOINT 'before_a';
    DO SOMETHING;
COMMIT TRANSACTION;

Транзакция ~ B

BEGIN TRANSACTION;
    DO SOMETHING_ELSE;
COMMIT TRANSACTION;

Транзакция ~ C

BEGIN TRANSACTION
    ROLLBACK TO COMMITED SAVEPOINT 'before_a'; -- discards work done in A and B
COMMIT TRANSACTION

Причина в том, что я пишу (Java) регрессионный тест.

При неправильных обстоятельствах DO SOMETHING_ELSE вызовет исключение фиксации транзакции при попытке фиксации B (некоторые нарушения ограничения внешнего ключа при удалении, я полагаю), но ТОЛЬКО если работа, выполненная в транзакции A, была зафиксирована.

Поскольку проблема сейчас решено, транзакция B совершит. Но при этом и A, и B оставят некоторые побочные продукты в базе данных. Теперь их необходимо удалить из базы данных, если предполагается, что следующий тест будет иметь какие-либо шансы на успех.

Чрезвычайно сложно отследить эти побочные продукты вручную, поэтому транзакция C должна удалить их.

1 Ответ

0 голосов
/ 10 апреля 2020

Как уже упоминалось в комментариях, это невозможно в PostgreSQL.

Ваша единственная надежда - использовать субтранзакции внутри конвертирующей транзакции:

BEGIN;
SAVEPOINT before_a;
/* perform the work for A */
/* perform the work for B */

Если B не удается, выполните следующие действия:

ROLLBACK TO SAVEPOINT before_a;

Затем, независимо от того, произошла ошибка B или нет:

/* perform the work for C */
COMMIT;
...