|
Программирование >> Программирование баз данных
Опция READ UNCOMMITTED Опция READ UNCOMMITTED представляет собой наиболее опасный из всех вариантов выбора уровня изоляции, но обеспечивает наивысшую производительность, измеряемую скоростью выполнения транзакции. Если уровень изоляции определен как READ UNCOMMITTED, то это служит для СУБД SQL Server )тсазанием на то, что не требуется устанавливать какие-либо блокировки, а также учитывать наличие каких-либо других блокировок. Если задан этот уровень изоляции, то пользователь может испытать на себе все возможные проблемы, связанные с нарушением правил параллельной организации работы, описанных выше в настояш,ей главе (причем наиболее важными из них является чтение незафиксированных данных). По какой причине разработчик молсет согласиться подвергнуться риску, который связан с чтением незафиксированных данных? Просматривая обсуждения в группах новостей Usenet, автор довольно часто обнаруживает, как те или иные разработчики снова и снова возвраш,аются к данному вопросу. Для многих это остается непонятным, но существуют довольно весомые причины для использования указанного уровня изоляции, и почти всегда они связаны с необходимостью формирования отчетов. В любой среде OLTP блокировки одновременно являются и вашим защитником, и вашим врагом. Блокировки позволяют предотвратить возникновение проблем нарушения целостности данных, но из-за них столь же часто предотвращается (или блокируется) возможность своеврсхменного получения требуемых данных. Слишком часто приходится сталкиваться с такой ситуацией, когда руководители компании требуют регулярно предоставлять им отчеты, а сотрудники компании, занимающиеся вводом данных, не имеют возможности вводить информацию или испытывают задержки при вводе из-за блокировок, установленных в связи с формированием отчетов для руководителей. Применение опции READ UNCOMMITTED часто позволяет обойти указанную проблему, по крайней мере при формировании отчетов, в которых не обязательно должны находиться абсолютно точные сведения. Например, предположим, что коммерческий директор желает лишь узнать, какой объем продаж достигнут за сегодняшний день до настоящего времени. Безусловно, подобное поведение характерно для чрезмерно придирчивого директора, который задает один и тот же вопрос много раз вдень (в форме повторного требования на получение одного и того же отчета), но мы обязаны выполнять это требование. Если для формирования отчета требуется продолжительное время, то повышается вероятность того, что из-за блокировки ресурсов, связанной с подготовкой отчета, будет приостановлена работа других сотрудников. Но у любого подобного отчета есть замечательное свойство - он требуется лишь для приблизительной оценки ситуации, поэтому сбор абсолютно точных данных для его формирования, по-видимому, не имеет смысла. Директору в действительности требуются лишь оценочные данные. Задавая для соответствующего запроса уровень изоляции READ UNCOMMITTED, мы не устанавливаем никаких блокировок, поэтому не препятствуем выполнению других транзакций. Безусловно, полученные при этом данные могут оказаться немного сомнительными (в связи с тем, что существует риск чтения незафиксированных данных), но так или иначе точные данные не требуются, к тому же известно, что итоговые значения все равно окажутся достаточно близкими к истинным, даже несмотря на наличие шансов, что произойдет откат и часть считанных данных будет относиться к незафиксированной транзакции. Такого же эффекта, как и при использовании опции READ UNCOMMITTED, можно добиться, введя запрос в подсказку оптимизатору NOLOCK. Но подход, в котором используется опция, определяющая уровень изоляции, имеет свое преимущество в том, что не требуется задавать подсказку для каждой таблицы в запросе или использовать ее в нескольких запросах. А преимущество использования подсказки оптимизатору NOLOCK состоит в том, что нет необходимости явно возвращаться к применяемому по умолчанию значению уровня изоляции для соединения после выполнения текущего оператора. (С другой стороны, при использовании опции READ UNCOMMITTED такая необходимость имеется.) Опция REPEATABLE READ Опция REPEATABLE READ обеспечивает определенную эскалацию уровня изоляции, что в значительной степени способствует повышению уровня защищенности параллельно выполняемых операций благодаря предотвращению чтения незафиксированных данных (эта задача решается и с помощью опции, предусмотренной по умолчанию), но вместе с тем исключает возможность неповторяемого чтения. Безусловно, такая возможность предотвращения неповторяемого чтения является важным достижением, но реализация этого режима не всегда оправдана. Дело в том, что сохранение даже разделяемых блокировок до конца транзакции исключает возможность получения доступа к заблокированным объектам другими пользователями, поэтому отрицательно сказывается на производительности. Сам автор предпочитает использовать другие способы обеспечения целостности данных (такие как применение ограничения CHECK в сочетании со средствами обработки ошибок), а не этот вариант, но в определенных ситуаци51х применение этой опции вполне оправдано. Уровню изоляции REPEATABLE READ соответствует эквивалентная подсказка оптимизатору REPEATABLEREAD (очевидно, что последнее ключевое слово отличается от первого лишь тем, что в нем отсутствует пробел). Опция SERIALIZABLE Опция SERIALIZABLE задает наиболее строгий из всех уровень изоляции. При ее использовании появляется возможность предотвратить возникновение всех форм нарушения правильной организации параллельной работы, кроме потерянных обновлений. Предотвращается даже возникновение фантомов. Установка уровня изоляции, равного SERIALIZABLE, равносильна указанию, что любые операторы, UPDATE, DELETE или INSERT, применяемые к той же таблице (или таблицам), которая используется в транзакции, не должны обращаться к тем же строкам, которые соответствуют условию WHERE любого оператора в этой транзакции. По существу, если любой другой пользователь собирается выполнить какие-либо действия надданными, представляющими интерес с точки зрения транзакции, для которой задана опция SERIALIZABLE, то он должен ожидать завершения этой транзакции. Режим работы с уровнем изоляции SERIALIZABLE можно также моделировать, используя в запросе подсказку оптимизатору SERIALIZABLE или HOLDLOCK. Кроме того, как и при сравнении опции READ UNCOMMITTED и подсказки оптимизатору NOLOCK, необходимо учитывать, что опция SERIALIZABLE в отличие от подсказки оптимизатору SERIALIZABLE или HOLDLOCK должна быть указана в операторе только один раз, но, с другой стороны, при использовании подсказки оптимизатору не нужно помнить о том, что необходимо восстанавливать прежнее значение уровня изоляции. На первый взгляд кажется, что лучше всего полностью перейти к использованию уровня изоляции SERIALIZABLE и отказаться от всех прочих опций. Безусяовно, применение этой опции позволяет обеспечить достижение в процессе эксплуатации базы данных наивысшего уровня проявления замечательной характеристики данных, известной под названием совместимости. Это означает, что операции модификации данных, одновременно выполняемые многочисленными пользователями, осуществляются так, как если бы в любой момент в базе данных выполнялась транзакция только одного пользователя (иными словами, обработка всех транзакций происходила бы последовательно). Тем не менее, как и за все хорошее в наилей жизни, за это также приходится платить. Практика показывает, что требования по обеспечению совместимости и достижению максимальной степени распараллеливания работы являются взаимоисключающими. Применение опции SERIALIZABLE может привести к тому, что другие пользователи не смогут получить доступ к тем объектам, которые для них требуются, а это равносильно уменьшению степени распараллеливания. Истинным является также противоположное утверждение - по мере увеличения степени распараллеливания (например, в результате перехода к использованию опции READ COMMITTED) совместимость данных в базе данных уменьшается. Личная рекомендация автора состоит в том, что следует придерживаться заданного по умолчанию значения (опции READ COMMITTED), если нет особых причин для отказа от этого. Организация работы в условиях появления взаимоблокировок (при возникновении ошибки с номером 1205) А теперь перейдем к новой теме. В предыдущих разделах приведены сведения о блокировках, а также описано, как блокировки применяются в транзакциях. На основании этих сведений можем перейти к рассмотрению довольно неприятной проблемы, связанной с возникновением взаимоблокировок. Как уже было сказано, взаимоблокировки как таковые не относятся к категории блокировок. Чаще всего они характеризуются тем, что под воздействием применяе-мьЕх блокировок возникает неразрешимая ситуация. С этим нарушением в работе рано или поздно приходится сталкиваться любому разработчику (особенно, если он не обладает достаточным опытом, чтобы обеспечить их предотвращение). О возникновении взаимоблокировки свидетельствует появление ошибки с номером 1205. Ситуация взаимоблокировки возникает настолько часто, что многие разработчики программного обеспечения для баз данных упоминают о ней просто по номеру. Взаимоблокировки возникают, если невозможно завершить какое-либо действие, необходимое для освобождения одной из блокировок, поскольку требуемый для этого ресурс удерживается второй блокировкой, и наоборот. Если обнаруживается такая ситуация, то одна из операций должна быть завершена аварийно, для того чтобы вторая операция была доведена до конца, поэтому в СУБД SQL Server осуществляется выбор жертвы взаимоблокировки. После этого происходит откат транзакции, выбранной в качестве жертвы взаимоблокировки, и передается сообщение с указанием
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |