Транзакции и курсоры
Транзакционный блок завершается командой SQL COMMIT, за которой также могут следовать необязательные ключевые слова WORK или TRANSACTION. В листинге 7.39 команда SQL COMMIT синхронизирует состояние базы данных с результатами команды UPDATE.
Листинг 7.39. Фиксация транзакции.
booktown-# BEGIN; BEGIN booktown=# UPDATE subjects SET location = NULL booktown-f WHERE id = 12; UPDATE 1 booktown=# SELECT location FROM subjects WHERE id -12: location (1 row) booktown=# COMMIT; COMMIT
Как видно из листинга, хотя результаты команды UPDATE немедленно отражаются на выборке, выполняемой командой SELECT, другие пользователи, подключенные к той же базе данных, ничего не будут знать о них вплоть до выполнения команды COMMIT.
Транзакции откатываются командой SQL ROLLBACK, за которой также могут следовать необязательные ключевые слова WORK или TRANSACTION.
В листинге 7.40 мы создаем транзакцию, вносим изменения в таблицу subjects и убеждаемся в их присутствии. Затем транзакция откатывается, и таблица возвращается к состоянию, в котором она находилась до начала транзакции.
Листинг 7.40. Откат транзакции.
booktown=# и BEGIN booktown=# SELECT * FROM subjects WHERE id = 12; id | subject | location 12 | Religion | (1 row) booktown=# UPDATE subjects SET location = 'Sunset Dr' booktown-# WHERE id = 12; UPDATE 1 booktown=# SELECT * FROM subjects WHERE id = 12; id | subject | location 12 | Religion | Sunset Dr (1 row) booktown=# ROLLBACK; ROLLBACK booktown=# SELECT * FROM subjects WHERE id = 12; id | subject I location 12 ] Religion | (1 row)
PostgreSQL предельно строго относится к ошибкам, возникающим при выполнении команд в транзакциях. Даже простейшие ошибки, вроде приведенной в листинге 7.41, переводят транзакцию в аварийное состояние. В этом состоянии запрещается выполнение любых команд, кроме команд завершения транзакции (COMMIT или ROLLBACK).
Листинг 7.41. Выход из аварийного состояния.
booktown=# BEGIN: BEGIN booktown=# SELECT * FROM; ERROR: parser: parse error at or near ";" booktown=# SELECT * FROM books; NOTICE: current transaction is aborted, queries ignored until end of transaction *ABORT STATE* booktown=# COMMIT;