FirebirdSQL logo
 Контекстные переменныеБезопасность 
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 игнорируется.