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, чтобы указать, какой снимок будет импортирован. Идентификатор должен быть записан в виде строкового литерала, например '00000003-0000001B-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 и т. д. Дополнительную информацию см. в главе Конфигурация сервера.

Аналогичным образом режимы текущей транзакции можно установить или просмотреть в параметрах конфигурации transaction_isolation, transaction_read_only и transaction_deferrable. Установка одного из этих параметров действует так же, как указание соответствующего параметра SET TRANSACTION, с теми же ограничениями по условиям применения. Однако эти параметры нельзя установить в файле конфигурации или из любого другого источника, кроме активного SQL.


Примеры

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

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 позволяет опустить запятые.