Могу ли я попросить Postgresql игнорировать ошибки в транзакции - PullRequest
15 голосов
/ 30 апреля 2010

Я использую Postgresql с расширениями PostGIS для специального пространственного анализа.Обычно я создаю и выдаю SQL-запросы вручную из psql.Я всегда заключаю сеанс анализа в транзакцию, поэтому, если я выполняю деструктивный запрос, я могу откатить его назад.

Однако, когда я запускаю запрос, содержащий ошибку, он отменяет транзакцию.Любые дальнейшие запросы вызывают следующее предупреждение:

ОШИБКА: текущая транзакция прервана, команды игнорируются до конца блока транзакции

Есть ли способ отключить это поведение?Утомительно откатывать транзакцию и повторять предыдущие запросы каждый раз, когда я делаю опечатку.

Ответы [ 5 ]

11 голосов
/ 30 апреля 2010

(ОБНОВЛЕНИЕ: нет необходимости делать это вручную, я спросил в списках рассылки postgresql, и оказалось, что это поведение уже реализовано с помощью ON_ERROR_ROLLBACK , установленного в клиенте psql)

Чтобы уточнить ответ Саймона (+1), в вашем сценарии вы могли бы регулярно добавлять точку сохранения после каждого интерактивного запроса, всегда с тем же именем (оно перезаписывает предыдущий, если запрос успешен). В случае ошибки вы возвращаетесь к последнему сохраненному и продолжаете оттуда.

Пример этого рабочего шаблона:

db=# select * from test_gral ;
 i |  t   |  n
---+------+------
 1 | text | 10.0
(1 row)

db=# begin;
BEGIN
db=#  insert into test_gral values (2,'xx',20); savepoint sp;
INSERT 0 1
SAVEPOINT
db=#  insert into test_gral values (3,'xx',30); savepoint sp;
INSERT 0 1
SAVEPOINT
db=#  insert into test_gralxx values (4,'xx',40); savepoint sp;
ERROR:  relation "test_gralxx" does not exist
LINE 1: insert into test_gralxx values (4,'xx',40);
                    ^
ERROR:  current transaction is aborted, commands ignored until end of transaction block
db=# ROLLBACK TO SAVEPOINT sp;
ROLLBACK
db=#  insert into test_gral values (4,'xx',40); savepoint sp;
INSERT 0 1
SAVEPOINT
db=# commit;
COMMIT
db=# select * from test_gral ;
 i |  t   |  n
---+------+------
 1 | text | 10.0
 2 | xx   |   20
 3 | xx   |   30
 4 | xx   |   40
(4 rows)
6 голосов
/ 30 апреля 2010

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

http://www.postgresql.org/docs/8.4/interactive/sql-savepoint.html

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

1 голос
/ 30 апреля 2010

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

0 голосов
/ 14 июля 2017

Простой ответ - запустить

my_db=> \set ON_ERROR_ROLLBACK interactive

в интерактивном сеансе. См. Также это сообщение в блоге его разработчиком.

0 голосов
/ 30 апреля 2010

Нет, это невозможно отключить. Ошибка неявно прерывает транзакцию для вас, поэтому вы должны выполнить откат и повторить попытку.

...