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