FirebirdSQL logo

Всё в Firebird выполняется в рамках транзакций.Транзакция — логическая единица изолированной работы группы последовательных операций над базой данных.Изменения над данными остаются обратимыми до тех пор, пока клиентское приложение не выдаст серверу инструкцию COMMIT.

Firebird имеет небольшое количество SQL операторов, которые могут использоваться клиентскими приложениями для старта, управления, подтверждения или отмены транзакций, но достаточное для всех задач над базой данных:

SET TRANSACTION

задание параметров транзакции и её старт;

COMMIT

завершение транзакции и сохранение изменений;

ROLLBACK

отмена изменений произошедший в рамках транзакции;

SAVEPOINT

установка точки сохранения для частичного отката изменений, если это необходимо;

RELEASE SAVEPOINT

удаление точки сохранения.

SET TRANSACTION

Назначение

Задаёт параметры транзакции и стартует её.

Доступно в

DSQL, ESQL

Синтаксис
SET TRANSACTION
   [NAME tr_name]
   [<tr_option> ...]

<tr_option> ::=
     READ {ONLY | WRITE}
   | [NO] WAIT
   | [ISOLATION LEVEL] <isolation level>
   | NO AUTO UNDO
   | RESTART REQUESTS
   | IGNORE LIMBO
   | LOCK TIMEOUT seconds
   | AUTO COMMIT
   | RESERVING <tables>
   | USING <dbhandles>


<isolation level> ::=
    SNAPSHOT [TABLE [STABILITY]]
  | SNAPSHOT AT NUMBER snapshot_number
  | READ COMMITTED [{[NO] RECORD_VERSION | READ CONSISTENCY}]

<tables> ::= <table_spec> [, <table_spec> ...]

<table_spec> ::= tablename [, tablename ...]
  [FOR [SHARED | PROTECTED] {READ | WRITE}]

<dbhandles> ::= dbhandle [, dbhandle ...]
Table 1. Параметры оператора SET TRANSACTION
Параметр Описание

tr_name

Имя транзакции.Доступно только в ESQL.

seconds

Время ожидания оператора (statement) в секундах при возникновении конфликта.

tables

Список таблиц для резервирования.

dbhandles

Список баз данных, к которым база данных может получить доступ.Доступно только в ESQL.

table_spec

Спецификация резервирования таблицы.

tablename

Имя таблицы для резервирования.

dbhandle

Хендл базы данных, к которой транзакция может получить доступ.Доступно только в ESQL.

snapshot number

Номер снимка другой транзакци, данные снимка базы данных которой должны быть общими с новой транзакцией.

Оператор SET TRANSACTION задаёт параметры транзакции и стартует её.Старт транзакции осуществляется только клиентскими приложениями, но не сервером (за исключением автономных транзакций и некоторых фоновых системных потоков/процессов, например, таких как sweep).

Каждое клиентское приложение может запускать произвольное количество одновременно выполняющихся транзакций.Фактически есть ограничение на общее количество выполняемых транзакций во всех клиентских приложениях, работающих с одной конкретной базой данных с момента последнего восстановления базы данных с резервной копии или с момента первоначального создания базы данных.Это количество равняется числу 248 -1 то есть ~ 2,8 x 1014 транзакций.В API и MON$ таблицах номер транзакции представляет собой 64 битное число.

Все предложения в операторе SET TRANSACTION являются необязательными.Если в операторе запуска транзакции на выполнение не задано никакого предложения, то предполагается старт транзакции со значениями всех характеристик по умолчанию (режим доступа, режим разрешения блокировок и уровень изолированности).

По умолчанию транзакция стартует со следующими характеристиками.

SET TRANSACTION
READ WRITE
WAIT ISOLATION LEVEL SNAPSHOT;

При старте со стороны клиента любой транзакции (заданной явно или по умолчанию) сервер передаёт клиенту дескриптор транзакции (целое число). На стороне сервера транзакциям последовательно присваиваются номера.Этот номер средствами SQL можно получить, используя контекстную переменную CURRENT_TRANSACTION.

docnext count = 24

Параметры транзакции

Основными характеристиками транзакции являются:

  • режим доступа к данным (READ WRITE, READ ONLY);

  • режим разрешения блокировок (WAIT, NO WAIT) с возможным дополнительным уточнением LOCK TIMEOUT;

  • уровень изоляции (READ COMMITTED, SNAPSHOT, SNAPSHOT TABLE STABILITY);

  • средства резервирования или освобождения таблиц (предложение RESERVING).

Имя транзакции

Необязательное предложение NAME задаёт имя транзакции.Предложение NAME доступно только в Embedded SQL.Если предложение NAME не указано, то оператор SET TRANSACTION применяется к транзакции по умолчанию.За счёт именованных транзакций позволяется одновременный запуск нескольких активных транзакций в одном приложении.При этом должна быть объявлена и инициализирована одноименная переменная базового языка.В DSQL, это ограничение предотвращает динамическую спецификацию имён транзакций.

Режим доступа

Для транзакций существует два режима доступа к данным базы данных: READ WRITE и READ ONLY.

  • При режиме доступа READ WRITE операции в контексте данной транзакции могут быть как операциями чтения, так и операциями изменения данных.Это режим по умолчанию.

  • В режиме READ ONLY в контексте данной транзакции могут выполняться только операции выборки данных SELECT.Любая попытка изменения данных в контексте такой транзакции приведёт к исключениям базы данных.Однако это не относиться к глобальным временным таблицам (GTT), которые разрешено модифицировать в READ ONLY транзакциях.

В Firebird API для режимов доступа предусмотрены следующие константы: isc_tpb_write соответствует режиму READ WRITE, isc_tpb_read — READ ONLY.

Режим разрешения блокировок

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

Блокировки также могут возникнуть и в других ситуациях при использовании некоторых уровней изоляции транзакций.

Существуют два режима разрешения блокировок: WAIT и NO WAIT.

Режим WAIT

В режиме WAIT (режим по умолчанию) при появлении конфликта с параллельными транзакциями, выполняющими конкурирующие обновления данных в той же базе данных, такая транзакция будет ожидать завершения конкурирующей транзакции путём её подтверждения (COMMIT) или отката (ROLLBACK). Иными словами, клиентское приложение будет переведено в режим ожидания до момента разрешения конфликта.

Если для режима WAIT задать предложение LOCK TIMEOUT, то ожидание будет продолжаться только указанное в этом предложении количество секунд.По истечении этого срока будет выдано сообщение об ошибке: “Lock time-out on wait transaction” (Истечение времени ожидания блокировки для транзакции WAIT).

Этот режим даёт несколько отличные формы поведения в зависимости от уровня изоляции транзакций.

В Firebird API режиму WAIT соответствует константа isc_tpb_wait.

Режим NO WAIT

Если установлен режим разрешения блокировок NO WAIT, то при появлении конфликта блокировки данная транзакция немедленно вызовет исключение базы данных.

В Firebird API режиму NO WAIT соответствует константа isc_tpb_nowait.

Note

LOCK TIMEOUT это отдельная опция транзакции, но может использоваться только для транзакций WAIT.Указание LOCK TIMEOUT с транзакцией NO WAIT вызовет ошибку “invalid parameter in transaction parameter block -Option isc_tpb_lock_timeout is not valid if isc_tpb_nowait was used previously in TPB”.

ISOLATION LEVEL

Уровень изолированности транзакций — значение, определяющее уровень, при котором в транзакции допускаются несогласованные данные, то есть степень изолированности одной транзакции от другой.Изменения, внесённые некоторым оператором, будут видны всем последующим операторам, запущенным в рамках этой же транзакции, независимо от её уровня изолированности.Изменения произведённые в рамках другой транзакции остаются невидимыми для текущей транзакции до тех пор, пока они не подтверждены.Уровень изолированности, а иногда, другие атрибуты, определяет, как транзакции будут взаимодействовать с другой транзакцией, которая хочет подтвердить изменения.

Необязательное предложение ISOLATION LEVEL задаёт уровень изолированности запускаемой транзакции.Это самая важная характеристика транзакции, которая определяет её поведение по отношению к другим одновременно выполняющимся транзакциям.

Существует три уровня изолированности транзакции:

  • SNAPSHOT

  • SNAPSHOT TABLE STABILITY

  • READ COMMITTED с уточнениями (NO RECORD_VERSION или RECORD_VERSION или READ CONSISTENCY)

Уровень изолированности SNAPSHOT

Уровень изолированности SNAPSHOT (уровень изолированности по умолчанию) означает, что этой транзакции видны лишь те изменения, фиксация которых произошла не позднее момента старта этой транзакции.Любые подтверждённые изменения, сделанные другими конкурирующими транзакциями, не будут видны в такой транзакции в процессе ее активности без её перезапуска.Чтобы увидеть эти изменения, нужно завершить транзакцию (подтвердить её или выполнить полный откат, но не откат на точку сохранения) и запустить транзакцию заново.

Note

Изменения, вносимые автономными транзакциями, также не будут видны в контексте той (“внешней”) транзакции, которая запустила эти автономные транзакции, если она работает в режиме SNAPSHOT.

В Firebird API режиму изолированности SNAPSHOT соответствует константа isc_tpb_concurrency.

Предложение AT NUMBER

Транзакцию с уровнем изолированности SNAPSHOT можно запустить на основе другой транзакции, если известен номер её снимка.В этом случае эта новая транзакция может видеть те же самые данные, что и транзакция на основе которой она запущена.

Эта функциональность позволяет создать параллельные процессы (в разных подключениях), считывающие согласованные данные из базы данных.Например, процесс резервного копирования может создавать несколько потоков, параллельно считывающих данные из базы данных.Или веб-служба работать с распределёнными вспомогательными службами, выполняя некоторую обработку.

Это достигается созданием транзакции с использованием синтаксиса

SET TRANSACTION SNAPSHOT  AT NUMBER snapshot_number

или через API с использованием константы isc_tpb_at_snapshot_number.

Значение snapshot_number из первой транзакции можно получить используя следующий запрос

RDB$GET_CONTEXT('SYSTEM', 'SNAPSHOT_NUMBER')

или через API информации о транзакции с константой fb_info_tra_snapshot_number.

Note

Обратите внимание, snapshot_number должен быть номером снимка активной транзакции.

Уровень изолированности SNAPSHOT TABLE STABILITY

Уровень изоляции транзакции SNAPSHOT TABLE STABILITY позволяет, как и в случае SNAPSHOT, также видеть только те изменения, фиксация которых произошла не позднее момента старта этой транзакции.При этом после старта такой транзакции в других клиентских транзакциях невозможно выполнение изменений ни в каких таблицах этой базы данных, уже каким-либо образом изменённых первой транзакцией.Все такие попытки в параллельных транзакциях приведут к исключениям базы данных.Просматривать любые данные другие транзакции могут совершенно свободно.

При помощи предложения резервирования RESERVING можно разрешить другим транзакциям изменять данные в некоторых таблицах.

Если на момент старта клиентом транзакции с уровнем изоляции SNAPSHOT TABLE STABILITY какая-нибудь другая транзакция выполнила неподтверждённое изменение данных любой таблицы базы данных, то запуск транзакции с таким уровнем изоляции приведёт к ошибке базы данных.

В Firebird API режиму изолированности SNAPSHOT TABLE STABILITY соответствует константа isc_tpb_consistency.

Уровень изолированности READ COMMITTED

Уровень изолированности READ COMMITTED позволяет в транзакции без её перезапуска видеть все подтверждённые изменения данных базы данных, выполненные в других параллельных транзакциях.Неподтверждённые изменения не видны в транзакциях этого уровня изолированности.

Для получения обновлённого списка строк интересующей таблицы необходимо лишь повторное выполнение оператора SELECT в рамках активной транзакции READ COMMITTED без её перезапуска.

В Firebird API режиму изолированности READ COMMITTED соответствует константа isc_tpb_read_committed.

RECORD_VERSION

Для этого уровня изолированности можно указать один из двух значений дополнительной характеристики в зависимости от желаемого способа разрешения конфликтов: RECORD_VERSION и NO RECORD_VERSION.Как видно из их имён они являются взаимоисключающими.

  • NO RECORD_VERSION является в некотором роде механизмом двухфазной блокировки. В этом случае транзакция не может прочитать любую запись, которая была изменена параллельной активной (неподтвержденной) транзакцией.

    • Если указана стратегия разрешения блокировок NO WAIT, то будет немедленно выдано соответствующее исключение.

    • Если указана стратегия разрешения блокировок WAIT, то это приведёт к ожиданию завершения или откату конкурирующей транзакции.Если конкурирующая транзакция откатывается, или, если она завершается и её идентификатор старее (меньше), чем идентификатор текущей транзакции, то изменения в текущей транзакции допускаются.Если конкурирующая транзакция завершается и её идентификатор новее (больше), чем идентификатор текущей транзакции, то будет выдана ошибка конфликта блокировок.

  • При задании RECORD_VERSION транзакция всегда читает последнюю подтверждённую версию записей таблиц, независимо от того, существуют ли изменённые и ещё не подтверждённые версии этих записей. В этом случае режим разрешения блокировок (WAIT или NO WAIT) никак не влияет на поведение транзакции при её старте.

В Firebird API для способа разрешения конфликтов NO RECORD_VERSION соответствует константа isc_tpb_no_rec_versionRECORD_VERSION — isc_tpb_rec_version.

Warning

Начиная с Firebird 4.0 эти опции являются устаревшими.По умолчанию они игнорируются и запускается транзакция READ COMMITTED READ CONSISTENCY.Это можно изменить установив параметр ReadConsistency (см. firebird.conf) в 0.В этом случае опции не игнорируются и работают точно так же как в предыдущих версиях.В будущих версиях этот параметр в firebird.conf может быть удалён.

READ CONSISTENCY

Если указана эта опция, то транзакция с режимом изолированности READ COMMITED делает стабильный снимок базы данных на время выполнения оператора.Каждый новый оператор верхнего уровня создаёт собственный моментальный снимок базы данных, чтобы видеть последние подтверждённые данные.Вложенные операторы (триггеры, вложенные хранимые процедуры и функции, динамические операторы и т.д.) используют тот же самый моментальный снимок базы данных, созданный оператором верхнего уровня.Таким образом обеспечивается согласованное чтение на момент начала выполнения оператора верхнего уровня.В Firebird 4.0 этот режим используется по умолчанию для транзакций с режимом изолированности READ COMMITED.

В Firebird API для стабильного снимка на уровне SQL оператора READ CONSISTENCY соответствует константа isc_tpb_read_consistency.

Обработка конфликта обновлений

Когда оператор выполняется в транзакции с режимом изолированности READ COMMITTED READ CONSISTENCY вид базы данных неизменен (подобно транзакции SNAPSHOT). Поэтому бесполезно ждать фиксации параллельной транзакции в надежде перечитать новую версию зафиксированной записи.При чтении поведение похоже на транзакцию READ COMMITTED RECORD_VERSION — оператор не ждёт завершения активной транзакции и обходит цепочку бекверсий, в которой ищет версию записи видимую для текущего моментального снимка.

Для режима изолированности READ COMMITTED READ CONSISTENCY обработка конфликтов обновлений Firebird значительно изменяется.При обнаружении конфликта обновления выполняется следующее:

  1. режим изолированности транзакции временно переключается в режим READ COMMITTED NO RECORD VERSION;

  2. Firebird устанавливает блокировку записи на конфликтную запись;

  3. Firebird продолжает оценивать оставшиеся записи для удаления/обновления в курсоре, а также продолжает ставить на них блокировки;

  4. когда больше нет записей для извлечения, запускается механизм для отмены всех выполненных действий, выполненных оператором верхнего уровня, и сохраняются все установленные блокировки для каждой обновлённой/удалённой/заблокированной записи, все вставленные записи удаляются;

  5. затем Firebird восстанавливает режим изолированности транзакции как READ COMMITTED READ CONSISTENCY, создаёт новый снимок уровня оператора и перезапускает выполнение оператора верхнего уровня.

Такой алгоритм позволяет гарантировать, что после перезапуска уже обновлённые записи останутся заблокированными, они будут видны новому снимку и могут быть обновлены снова без дальнейших конфликтов.Кроме того, из-за режима согласованности чтения набор изменённых записей остаётся согласованным.

Note
Замечания
  • Приведённый выше алгоритм перезапуска применяется к операторам UPDATE, DELETE, SELECT WITH LOCK и MERGE, с предложением RETURNING и без него, выполняемым непосредственно из пользовательского приложения или в составе некоторого объекта PSQL (хранимая процедура, функция, триггер, EXECUTE BLOCK и т. д.);

  • если оператор UPDATE/DELETE расположена на каком-то явном курсоре (WHERE CURRENT OF), то Firebird пропускает шаг (c) выше, то есть не извлекает и не устанавливает блокировки записи для оставшихся записей курсора;

  • если оператор верхнего уровня SELECT (или EXECUTE BLOCK возвращающий набор данных) и конфликт обновления происходит после того, как одна или несколько записей были возвращены приложению, то ошибка конфликта обновления сообщается как обычно и перезапуск не инициируется;

  • рестарт не инициируется для операторов в автономных блоках (IN AUTONOMOUS TRANSACTION DO …​);

  • после 10 попыток Firebird прерывает алгоритм перезапуска, снимает все блокировки записи, восстанавливает режим изоляции транзакции как READ COMMITTED READ CONSISTENCY и сообщает о конфликте обновления;

  • любая не обработанная ошибка на шаге (c) выше останавливает алгоритм перезапуска, и Firebird продолжает обработку обычным способом, например, ошибка может быть перехвачена и обработана блоком PSQL WHEN или сообщена приложению, если она не обработана;

  • триггеры UPDATE/DELETE сработают многократно для одной и той же записи, если выполнение оператора было перезапущено и запись обновлена/удалена снова;

  • по историческим причинам isc_update_conflict сообщается как вторичный код ошибки с первичным кодом ошибки isc_deadlock.

NO AUTO UNDO

При использовании опции NO AUTO UNDO оператор ROLLBACK только помечает транзакцию как отменённую без удаления созданных в этой транзакции версий, которые будут удалены позднее в соответствии с выбранной политикой сборки мусора (см. параметр GCPolicy в firebird.conf).

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

Для транзакций, в рамках которых не выполняется никаких изменений, опция NO AUTO UNDO игнорируется.

IGNORE LIMBO

При указании опции IGNORE LIMBO игнорируются записи, создаваемые “потерянными” (т.е.не завершёнными) транзакциями (limbo transaction). Транзакции считается “потерянной”, если не завершён второй этап двухфазного подтверждения (two-phase commit).

AUTO COMMIT

При указании опции AUTO COMMIT транзакция автоматически подтверждается после успешного выполнения любого оператора.Если в процессе выполнения оператора произойдёт ошибка, то транзакция будет откачена.После подтверждения или отката транзакция продолжает оставаться активной, сохраняя свой идентификатор.

Important

Опция AUTO COMMIT использует “мягкое” подтверждение (COMMIT RETAIN) и “мягкий” откат (ROLLBACK RETAIN) транзакции.Мягкое подтверждение не освобождает ресурсов сервера и удерживает сборку мусора, что может негативно отразиться на производительности.

RESERVING

Предложение RESERVING в операторе SET TRANSACTION резервирует указанные в списке таблицы.Резервирование запрещает другим транзакциям вносить в эти таблицы изменения или (при определённых установках характеристик предложения резервирования) даже читать данные из этих таблиц, в то время как выполняется данная транзакция.Либо, наоборот, в этом предложении можно указать список таблиц, в которые параллельные транзакции могут вносить изменения, даже если запускается транзакция с уровнем изоляции SNAPSHOT TABLE STABILITY.

В одном предложении резервирования можно указать произвольное количество резервируемых таблиц используемой базы данных.

Если опущено одно из ключевых слов SHARED или PROTECTED, то предполагается SHARED.Если опущено все предложение FOR, то предполагается FOR SHARED READ.Варианты осуществления резервирования таблиц по их названиям не являются очевидными.

Table 1. Совместимости различных блокировок

 

SHARED READ

SHARED WRITE

PROTECTED READ

PROTECTED WRITE

SHARED READ

да

да

да

да

SHARED WRITE

да

да

нет

нет

PROTECTED READ

да

нет

да

нет

PROTECTED WRITE

да

нет

нет

нет

Для транзакции запущенной в режиме изолированности SNAPSHOT для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изоляции допустимы при различных способах их резервирования следующие варианты поведения:

  • SHARED READ — не оказывает никакого влияния на выполнение параллельных транзакций;

  • SHARED WRITE — на поведение параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED не оказывает никакого влияния, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;

  • PROTECTED READ — допускает только чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности, попытка внесения изменений приводит к исключению базы данных;

  • PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED запрещает запись в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает также и чтение данных из резервируемых таблиц.

Для транзакции запущенной в режиме изолированности SNAPSHOT TABLE STABILITY для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изолированности допустимы при различных способах их резервирования следующие варианты поведения:

  • SHARED READ — позволяет всем параллельным транзакциям независимо от их уровня изолированности не только читать, но и выполнять любые изменения в резервируемых таблицах (если параллельная транзакция имеет режим доступа READ WRITE);

  • SHARED WRITE — для всех параллельных транзакций с уровнем доступа READ WRITE и с уровнями изолированности SNAPSHOT и READ COMMITTED позволяет читать данные из таблиц и писать данные в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;

  • PROTECTED READ — допускает только лишь чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности;

  • PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED запрещает запись в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает также и чтение данных из резервируемых таблиц.

Для транзакции запущенной в режиме изолированности READ COMMITTED для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изоляции допустимы при различных способах их резервирования следующие варианты поведения:

  • SHARED READ — позволяет всем параллельным транзакциям независимо от их уровня изолированности не только читать, но и выполнять любые изменения в резервируемых таблицах (при уровне доступа READ WRITE);

  • SHARED WRITE — для всех транзакций с уровнем доступа READ WRITE и с уровнями изолированности SNAPSHOT и READ COMMITTED позволяет читать и писать данные в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;

  • PROTECTED READ — допускает только чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности;

  • PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED разрешает только чтение данных и запрещает запись в указанные в данном списке таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только изменение данных, но и чтение данных из резервируемых таблиц.

Tip

Предложение USING может быть использовано для сохранения системных ресурсов за счёт ограничения количества баз данных, к которым имеет доступ транзакция.Доступно только в Embedded SQL.

См. также:

COMMIT, ROLLBACK.

COMMIT

Назначение

Подтверждение транзакции.

Доступно в

DSQL, ESQL

Синтаксис
COMMIT [WORK] [TRANSACTION tr_name]
  [RELEASE] [RETAIN [SNAPSHOT]];
Table 1. Параметры оператора COMMIT
Параметр Описание

tr_name

Имя транзакции.Доступно только в ESQL.

Оператор COMMIT подтверждает все изменения в данных, выполненные в контексте данной транзакции (добавления, изменения, удаления). Новые версии записей становятся доступными для других транзакций, и если предложение RETAIN не используется, то освобождаются все ресурсы сервера, связанные с выполнением данной транзакции.

Если в процессе подтверждения транзакции возникли ошибки в базе данных, то транзакция не подтверждается.Пользовательская программа должна обработать ошибочную ситуацию и заново подтвердить транзакцию или выполнить её откат.

Необязательное предложение TRANSACTION задаёт имя транзакции.Предложение TRANSACTION доступно только в Embedded SQL.Если предложение TRANSACTION не указано, то оператор COMMIT применяется к транзакции по умолчанию.

Note

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

Необязательное ключевое слово WORK может быть использовано лишь для совместимости с другими системами управления реляционными базами данных.

Ключевое слово RELEASE доступно только в Embedded SQL.Оно позволяет отключиться ото всех баз данных после завершения текущей транзакции. RELEASE поддерживается только для обратной совместимости со старыми версиями Interbase.В настоящее время вместо него используется оператор ESQL DISCONNECT.

Если используется предложение RETAIN [SNAPSHOT], то выполняется так называемое мягкое (soft) подтверждение.Выполненные действия в контексте данной транзакции фиксируются в базе данных, а сама транзакция продолжает оставаться активной, сохраняя свой идентификатор, а также состояние курсоров, которое было до мягкой фиксации транзакции.В этом случае нет необходимости опять стартовать транзакцию и заново выполнять оператор SELECT для получения данных.

Если уровень изоляции такой транзакции SNAPSHOT или SNAPSHOT TABLE STABILITY, то после мягкого подтверждения транзакция продолжает видеть состояние базы данных, которое было при первоначальном запуске транзакции, то есть клиентская программа не видит новых подтверждённых результатов изменения данных других транзакций.Кроме того, мягкое подтверждение не освобождает ресурсов сервера (открытые курсоры не закрываются).

Tip

Для транзакций, которые выполняют только чтение данных из базы данных, рекомендуется также использовать оператор COMMIT, а не ROLLBACK, поскольку этот вариант требует меньшего количества ресурсов сервера и улучшает производительность всех последующих транзакций.

См. также:

SET TRANSACTION, ROLLBACK.

ROLLBACK

Назначение

Откат транзакции.

Доступно в

DSQL, ESQL

Синтаксис
ROLLBACK [WORK] [TRANSACTION tr_name]
  [RETAIN [SNAPSHOT] | TO SAVEPOINT sp_name] [RELEASE];
Table 1. Параметры оператора ROLLBACK
Параметр Описание

tr_name

Имя транзакции.Доступно только в ESQL.

sp_name

Имя точки сохранения.Доступно только в DSQL.

Оператор ROLLBACK отменяет все изменения данных базы данных (добавление, изменение, удаление), выполненные в контексте этой транзакции.Оператор ROLLBACK никогда не вызывает ошибок.Если не указано предложение RETAIN, то при его выполнении освобождаются все ресурсы сервера, связанные с выполнением данной транзакции.

Необязательное предложение TRANSACTION задаёт имя транзакции.Предложение TRANSACTION доступно только в Embedded SQL.Если предложение TRANSACTION не указано, то оператор ROLLBACK применяется к транзакции по умолчанию.

Note

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

Необязательное ключевое слово WORK может быть использовано лишь для совместимости с другими системами управления реляционными базами данных.

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

Для уровней изоляции SNAPSHOT и SNAPSHOT TABLE STABILITY состояние базы данных остаётся в том виде, которое база данных имела при первоначальном старте такой транзакции, однако в случае уровня изоляции READ COMMITTED база данных будет иметь вид, соответствующий новомусостоянию на момент выполнения оператора ROLLBACK RETAIN.В случае отмены транзакции с сохранением её контекста нет необходимости заново выполнять оператор SELECT для получения данных из таблицы.

См. также:

SET TRANSACTION, COMMIT.

ROLLBACK TO SAVEPOINT

Необязательное предложение TO SAVEPOINT в операторе ROLLBACK задаёт имя точки сохранения, на которую происходит откат.В этом случае отменяются все изменения, произошедшие в рамках транзакции, начиная с созданной точки сохранения (SAVEPOINT).

Оператор ROLLBACK TO SAVEPOINT выполняет следующие операции:

  • Все изменения в базе данных, выполненные в рамках транзакции начиная с созданной точки сохранения, отменяются. Пользовательские переменные, заданные с помощью функции RDB$SET_CONTEXT() остаются неизменными;

  • Все точки сохранения, создаваемые после названной, уничтожаются. Все более ранние точки сохранения, как сама точка сохранения, остаются. Это означает, что можно откатываться к той же точке сохранения несколько раз;

  • Все явные и неявные блокированные записи, начиная с точки сохранения, освобождаются. Другие транзакции, запросившие ранее доступ к строкам, заблокированным после точки сохранения, должны продолжать ожидать, пока транзакция не фиксируется или откатывается. Другие транзакции, которые ещё не запрашивали доступ к этим строкам, могут запросить и сразу же получить доступ к разблокированным строкам.

См. также:

SAVEPOINT.

SAVEPOINT

Назначение

Создание точки сохранения.

Доступно в

DSQL

Синтаксис
SAVEPOINT sp_name
Table 1. Параметры оператора SAVEPOINT
Параметр Описание

sp_name

Имя точки сохранения.Должно быть уникальным в рамках транзакции.

Оператор SAVEPOINT создаёт SQL:99 совместимую точку сохранения, к которой можно позже откатывать работу с базой данных, не отменяя все действия, выполненные с момента старта транзакции.Механизмы точки сохранения также известны под термином “вложенные транзакции” (“nested transactions”).

Если имя точки сохранения уже существует в рамках транзакции, то существующая точка сохранения будет удалена, и создаётся новая с тем же именем.

Для отката изменений к точке сохранения используется оператор ROLLBACK TO SAVEPOINT.

Note

Внутренний механизм точек сохранения может использовать большие объёмы памяти, особенно если вы обновляете одни и те же записи многократно в одной транзакции.Если точка сохранения уже не нужна, но вы ещё не готовы закончить транзакцию, то можно её удалить оператором RELEASE SAVEPOINT, тем самым освобождая ресурсы.

Example 1. DSQL сессия с использованием точек сохранения
CREATE TABLE TEST (ID INTEGER);
COMMIT;
INSERT INTO TEST VALUES (1);
COMMIT;
INSERT INTO TEST VALUES (2);
SAVEPOINT Y;
DELETE FROM TEST;
SELECT * FROM TEST; -- возвращает пустую строку
ROLLBACK TO Y;
SELECT * FROM TEST; -- возвращает две строки
ROLLBACK;
SELECT * FROM TEST; -- возвращает одну строку

RELEASE SAVEPOINT

Назначение

Удаление точки сохранения.

Доступно в

DSQL

Синтаксис
RELEASE SAVEPOINT sp_name [ONLY]
Table 1. Параметры оператора RELEASE SAVEPOINT
Параметр Описание

sp_name

Имя точки сохранения.

Оператор RELEASE SAVEPOINT удаляет именованную точку сохранения, освобождая все связанные с ней ресурсы.По умолчанию удаляются также все точки сохранения, создаваемые после указанной.Если указано предложение ONLY, то удаляется только точка сохранения с заданным именем.

См. также:

SAVEPOINT.

Внутренние точки сохранения

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

Когда объем изменений, выполняемых под системной точкой сохранения уровня транзакции, становиться большим (затрагивается порядка 50000 записей), сервер освобождает системную точку сохранения и, при необходимости отката транзакции, использует механизм TIP.

Tip

Если вы ожидаете, что объем изменений в транзакции будет большим, то можно задать опцию NO AUTO UNDO в операторе SET TRANSACTION, или — если используется API — установить флаг TPB isc_tpb_no_auto_undo.В обеих вариантах предотвращается создание системной точки сохранения уровня транзакции.

Точки сохранения и PSQL

Использование операторов управления транзакциями в PSQL не разрешается, так как это нарушит атомарность оператора, вызывающего процедуру.Но Firebird поддерживает вызов и обработку исключений в PSQL, так, чтобы действия, выполняемые в хранимых процедурах и триггерах, могли быть выборочно отменены без полного отката всех действий в них.Внутренне автоматические точки сохранения используется для:

  • отмены всех действий внутри блока BEGIN …​ END, где происходит исключение;

  • отмены всех действий, выполняемых в хранимой процедуре/триггере (или, в случае селективной хранимой процедуры, всех действий, выполненных с момента последнего оператора SUSPEND), если они завершаются преждевременно из-за непредусмотренной ошибки или исключения.

Каждый блок обработки исключений PSQL также ограничен автоматическими точками сохранения сервера.

Note

Сами по себе блок BEGIN …​ END не создаёт автоматическую точку сохранения.Она создаётся только в блоках, которых присутствует блок WHEN для обработки исключений или ошибок.