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