Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
"Средним" уровнем изоляции является SNAPSHOT, альтернативно называемый Repeatabie Read (повторяемое чтение) или concurrency (параллельность). При этом изоляция SNAPSHOT В Firebird не является в точности соответствующей уровню Repeatabie Read, как он определен в стандарте. Он изолирует вид базы данных для транзакции изменениями на уровне строк только для существующих строк. При этом, поскольку по своей природе многоверсионная архитектура полностью изолирует транзакции SNAPSHOT от новых строк, подтвержденных другими транзакциями, не предоставляя транзакциям SNAPSHOT доступ к глобальному образу состояния транзакций (TSB, см. главу 25), транзакции SNAPSHOT не могут видеть фантомные строки. Следовательно, транзакции SNAPSHOT
Пока SNAPSHOT еще не идентичен SERIALIZABLE, потому что другие транзакции могут изменять и удалять строки, которые находятся в зоне видимости транзакции SERIALIZABLE.
Транзакция гарантирует неизменный вид базы данных, который до завершения транзакции не будет зависеть от любых подтвержденных изменений в других транзакциях. Такой уровень полезен для "исторических" задач, таких как формирование отчетов или экспорт данных, которые могут оказаться ошибочными, если не будут выполняться с воспроизводимым видом данных.
SNAPSHOT является уровнем изоляции по умолчанию для инструмента обработки запросов isql, а также для многих компонентов и драйверов интерфейса.
Самым "глубоким" уровнем изоляции является SNAPSHOT TABLE STABILITY, альтернативно называемый consistency, потому что он гарантирует получение данных в неизменном состоянии, который останется внешне согласованным в пределах базы данных, пока продолжается транзакция. Транзакции чтения/записи не могут даже читать таблицы, которые блокируются транзакцией с таким уровнем изоляции.
Блокировка на уровне таблицы, создаваемая этим уровнем изоляции, включает в себя все таблицы, к которым осуществляет доступ транзакция, включая те, которые связаны ссылочными ограничениями.
Этот уровень устанавливает агрессивное расширение, которое гарантирует сериализацию в строгом смысле, т. е. никакая другая транзакция не может добавлять или удалять - вообще изменять - строки в используемых таблицах, если любая транзакция получает дескриптор с этим уровнем изоляции. Наоборот, транзакция TABLE STABILITY не сможет получить дескриптор, если какая-нибудь транзакция чтения/записи в настоящий момент читает любую таблицу, которая находится в зоне видимости этой транзакции. В терминах стандарта это не обязательно, поскольку изоляция SNAPSHOT уже защищает транзакции от всех трех феноменов, управляемых уровнем SERIALIZABLE в стандарте SQL.
Транзакция consistency еще называется блокирующей транзакцией, потому что она блокирует доступ любых других транзакций чтения/записи к любым записям, к которым эта транзакция обращается, и к любым записям, зависящим от этих записей.
! ! !
ВНИМАНИЕ! Поскольку этот уровень потенциально блокирует часть базы данных для других пользователей, которым нужно выполнять изменения, SNAPSHOT TABLE STABILITY должен использоваться осторожно. Внимательно следите за размером применяемых наборов, воздействием на соединения, зависимые таблицы и особенно за длительностью такой транзакции.
. ! .
Способ доступа
Способ доступа может быть READ WRITE (чтение/запись) или READ ONLY (только чтение). Транзакция READ WRITE может выбирать, добавлять, изменять и удалять данные. Транзакция READ ONLY может только выбирать данные.
Способом доступа по умолчанию является READ WRITE.
! ! !
СОВЕТ. Одним из преимуществ транзакции READ ONLY является ее способность выбирать записи для пользовательского интерфейса без использования большого объема
ресурсов на сервере. Убедитесь, что ваши транзакции только для чтения сконфигурированы с уровнем изоляции READ COMMITTED, чтобы гарантировать, что сборка мусора на сервере будет выполняться, минуя эту транзакцию.. ! .
Способ разрешения блокировок ("Режим блокировок")
Способ разрешения блокировок определяет поведение транзакции в случае, когда она пытается отправить изменение, которое конфликтует с изменением, уже отправленным другой транзакцией. Значениями являются WAIT и NOWAIT.
WAIT (по умолчанию) приводит к тому, что транзакция будет ожидать, пока заблокированные строки ожидающей завершения транзакцией не будут освобождены прежде, чем она станет определять, может ли эта транзакция их изменять. Если другая транзакция отправит более новую версию записи, то ожидающая транзакция выдаст сообщение, что возник конфликт блокировки.
WAIT чаще всего не является предпочтительным способом блокировки для интерактивных систем с большим объемом данных, потому что он может замедлять работу пользователей и при некоторых условиях может приводить к тупикам (см. разд. "Что такое взаимная блокировка?").
Использование WAIT бессмысленно в изоляции SNAPSHOT. Если только блокирующая транзакция в итоге не выполнит откат- наименее вероятный сценарий- результатом ожидания, естественно, будет конфликт блокировки. В транзакции READ COMMITTED вероятность того, что результатом ожидания будет конфликт блокировки, весьма мала.
Это не означает, что вариант WAIT не будет полезным при некоторых условиях. Если обработчик исключений в клиентском приложении обрабатывает конфликты, постоянно повторяя обращение без пауз, то перегрузка системы, вызванная этими постоянными повторениями и отказами, будет большим злом, чем, если бы было указано WAIT, особенно если блокирующая транзакция требует много времени для завершения. В сравнении с этим WAIT может приводить только к одному исключению, обрабатываемому с помощью одного отката.
Когда вероятность столкновений транзакций высока, но транзакции короткие, WAIT является предпочтительным, потому что гарантирует, что ожидающие запросы будут обрабатываться в последовательности FIFO (First In First Out, первый пришел - первый ушел). При этом в пользовательских системах, где быстрые операции не гарантированы, транзакции WAIT противопоказаны, потому что потенциально задерживают сборку мусора.
В транзакции NO WAIT сервер немедленно сообщит клиенту об обнаружении новой неподтвержденной версии строки, которую пытается изменять транзакция. В разумно нагруженных многопользовательских системах NO WAIT часто является предпочтительным для устранения риска перегрузки системы ожидающими транзакциями.
По эмпирическому правилу для транзакций SNAPSHOT производительность будет выше, а пользовательские интерфейсы более оперативными, если клиентское приложение выберет NO WAIT и будет обрабатывать конфликты блокировок, используя откат, синхронизированный повтор операции или другие подходящие техники.
Резервирование таблиц
Firebird поддерживает режим блокировки таблиц для обеспечения полной блокировки одной или более таблиц в процессе выполнения транзакции. Необязательное предложение RESERVING <список таблиц> запрашивает немедленную полную блокировку всех подтвержденных строк указанных таблиц, предоставляя транзакции исключительный доступ за счет любых транзакций, конкурирующих с этой транзакцией.