SET TRANSACTION
SET TRANSACTION — установить характеристики текущей транзакции
Синтаксис
SET TRANSACTION режим_транзакции [, ...]
SET TRANSACTION SNAPSHOT id_снимка
SET SESSION CHARACTERISTICS AS TRANSACTION режим_транзакции [, ...]
где режим_транзакции является одним из следующих:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
[ NOT ] DEFERRABLE
Описание
Команда SET TRANSACTION
задает характеристики текущей транзакции. Она не
влияет на последующие транзакции. SET SESSION CHARACTERISTICS
задает характеристики транзакции по умолчанию для последующих транзакций
сеанса. Затем эти характеристики по умолчанию можно переопределить для отдельной
транзакции командой SET TRANSACTION
.
Доступные характеристики транзакции — это уровень изоляции транзакции, режим доступа к транзакции (чтение/запись или только чтение) и режим отложенного доступа. Кроме того, можно выбрать снимок, но только для текущей транзакции, а не для сеанса по умолчанию.
Уровень изоляции транзакции определяет, какие данные транзакция может видеть, когда параллельно выполняются другие транзакции:
READ COMMITTED
Оператор может видеть только строки, зафиксированные до начала выполнения транзакции. Это значение по умолчанию.
REPEATABLE READ
Все операторы текущей транзакции могут видеть только строки, зафиксированные до выполнения первого запроса или оператора изменения данных в этой транзакции.
SERIALIZABLE
Все операторы текущей транзакции могут видеть только строки, зафиксированные до выполнения первого запроса или оператора изменения данных в этой транзакции. Если наложение операций чтения и записи среди параллельных сериализуемых транзакций создаст ситуацию, невозможную при однопоточном (поочередном) их выполнении, произойдет откат одной из транзакций с ошибкой serialization_failure (сбой сериализации).
Стандарт SQL определяет один дополнительный уровень, READ UNCOMMITTED. В QHB READ UNCOMMITTED трактуется как READ COMMITTED.
Уровень изоляции транзакции не может быть изменен после выполнения
первого запроса или оператора изменения данных (SELECT
,
INSERT
, DELETE
, UPDATE
, FETCH
или COPY
) в текущей транзакции.
Дополнительную информацию об изоляции транзакции см. в главе
Управление параллельным доступом.
Режим доступа к транзакции определяет, является ли транзакция доступной
для чтения/записи или только для чтения. Чтение/запись — это поведение по умолчанию.
Когда транзакция доступна только для чтения, запрещены следующие команды SQL:
INSERT
, UPDATE
, DELETE
и COPY FROM
(если таблица, в
которую будут писать, не является временной таблицей), любые команды CREATE
,
ALTER
и DROP
, а также COMMENT
, GRANT
, REVOKE
, TRUNCATE
;
EXPLAIN ANALYZE
и EXECUTE
запрещаются, если команда, которую они будут
выполнять, находится в числе вышеперечисленных. Это высокоуровневое определение
режима только для чтения, которое не препятствует записи на диск.
Свойство DEFERRABLE транзакции не имеет эффекта, если транзакция не находится в режиме SERIALIZABLE и READ ONLY. Если для транзакции выбраны все три этих свойства, она может быть заблокирована при первой попытке получить свой снимок данных, после чего сможет выполняться без обычных для режима SERIALIZABLE накладных расходов и без какого-либо риска пострадать или быть отмененной из-за сбоя сериализации. Этот режим хорошо подходит для длительных построений отчетов или выполнения резервных копий.
Команда SET TRANSACTION SNAPSHOT
позволяет выполнить новую транзакцию с тем
же снимком данных, что и существующая транзакция. Ранее существовавшая
транзакция должна экспортировать этот снимок с помощью функции
pg_export_snapshot (см. раздел Функции синхронизации снимков). Эта функция
возвращает идентификатор снимка, который необходимо передать команде
SET TRANSACTION SNAPSHOT
, чтобы указать, какой снимок будет импортирован.
Идентификатор должен быть записан в виде строковой константы, например
’000003A1-1’. SET TRANSACTION SNAPSHOT
может выполняться только в начале
транзакции, до выполнения первого запроса или оператора изменения данных
(SELECT
, INSERT
, DELETE
, UPDATE
, FETCH
или COPY
) этой транзакции.
Более того, в транзакции уже должен быть установлен уровень изоляции
SERIALIZABLE или REPEATABLE READ (иначе снимок будет
немедленно удален, так как на уровне READ COMMITTED создается новый снимок
для каждой команды). Если импортирующая транзакция имеет уровне изоляции
SERIALIZABLE, то транзакция, экспортировавшая снимок, тоже должна
использовать этот уровень изоляции. Кроме того, сериализуемая транзакция в режиме чтение/запись
не может импортировать снимок из транзакции в режиме «только чтение».
Примечания
При выполнении команды SET TRANSACTION
без предварительного выполнения
START TRANSACTION
или BEGIN
будет выдано предупреждение и больше ничего
не произойдет.
Можно обойтись без SET TRANSACTION
, указав вместо нее желаемый
режим_транзакции в операторах BEGIN
или START TRANSACTION
.
Но такой возможности не предусмотрено для SET TRANSACTION SNAPSHOT
.
Режимы транзакций сеанса по умолчанию также можно задать в
параметрах конфигурации default_transaction_isolation,
default_transaction_read_only и default_transaction_deferrable.
(На самом деле SET SESSION CHARACTERISTICS
— это более многословная
альтернатива для установки этих переменных с помощью команды SET
.) Это
означает, что значения по умолчанию могут быть установлены в файле
конфигурации, через ALTER DATABASE
и т.д. Дополнительную информацию см.
в главе Конфигурация сервера.
Примеры
Чтобы начать новую транзакцию со снимком данных, который получила уже существующая транзакция, его нужно сначала экспортировать из первой транзакции. При этом будет получен идентификатор снимка, например:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT pg_export_snapshot();
pg_export_snapshot
---------------------
00000003-0000001B-1
(1 строка)
Затем этот идентификатор нужно передать команде
SET TRANSACTION SNAPSHOT
в начале новой транзакции:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
Совместимость
Эти команды определены в стандарте SQL, за исключением режима транзакции
DEFERRABLE и формы SET TRANSACTION SNAPSHOT
, которые являются
расширениями QHB.
В стандарте уровнем изоляции транзакции по умолчанию является SERIALIZABLE. В QHB обычно используется значение по умолчанию READ COMMITTED, но, как упоминалось выше, его можно изменить.
В стандарте SQL есть еще одна характеристика транзакции, которую нельзя задать с помощью этих команд: размер диагностической области. Эта концепция специфична для встраиваемого SQL и поэтому не реализована в сервере QHB.
Стандарт SQL требует запятых между последовательными режимами_транзакции, но по историческим причинам QHB позволяет опустить запятые.