Следующая ссылка в руководстве по документации PostgreSQL http://www.postgresql.org/docs/8.3/interactive/populate.html гласит, что для отключения автоматической фиксации в postgreSQL вы можете просто поместить все операторы вставки в BEGIN; и COMMIT;
Однако я испытываю трудности с фиксацией любых исключений, которые могут произойти между BEGIN; COMMIT; и если происходит ошибка (например, попытка вставить дублирующийся PK), у меня нет возможности явно вызывать команды ROLLBACK или COMMIT. Хотя все операторы вставки автоматически откатываются, PostgreSQL все еще ожидает явного вызова команд COMMIT или ROLLBACK, прежде чем он сможет считать транзакцию завершенной. В противном случае сценарий должен ожидать истечения времени ожидания транзакции, и любые последующие операторы вызовут ошибку.
В хранимой процедуре вы можете использовать предложение EXCEPTION, чтобы сделать это, но это не относится к моим обстоятельствам выполнения массовых вставок. Я пробовал это, и блок исключения не работал для меня, потому что следующий оператор (ы), выполненный после того, как ошибка имеет место, не выполняется с ошибкой:
ERROR: current transaction is aborted, commands ignored until end of transaction block
Транзакция остается открытой, так как она не была явно завершена с вызовом COMMIT или ROLLBACK;
Вот пример кода, который я использовал для проверки этого:
BEGIN;
SET search_path TO testing;
INSERT INTO friends (id, name) VALUES (1, 'asd');
INSERT INTO friends (id, name) VALUES (2, 'abcd');
INSERT INTO friends (id, nsame) VALUES (2, 'abcd'); /*note the deliberate mistake in attribute name and also the deliberately repeated pk value number 2*/
EXCEPTION /* this part does not work for me */
WHEN OTHERS THEN
ROLLBACK;
COMMIT;
При использовании такой техники действительно ли я должен гарантировать, что все утверждения будут успешными? Почему это так? Разве нет способа перехватить ошибки и явно вызвать откат?
Спасибо