|
Программирование >> Oracle
Что такое блокировки? Блокировка - это механизм, используемый для управления одновременным доступом к общему ресурсу. Обратите внимание: использован термин общий ресурс , а не строка таблицы . Сервер Oracle действительно блокирует данные таблицы на уровне строк, но для обеспечения одновременного доступа к различным ресурсам он использует блокировки и на других уровнях. Например, при выполнении хранимой процедуры она блокируется в режиме, который позволяет другим сеансам ее выполнять, запрещая при этом изменять ее. Блокировки используются в базе данных для одновременного доступа к общим ресурсам и обеспечения при этом целостности и согласованности данных. В однопользовательской базе данных блокировки не нужны. У них по определению только один пользователь, изменяющий информацию. Однако если данные или структуры данных читаются и изменяются несколькими пользователями, важно иметь штатный механизм предотвращения одновременных изменений одного и того же фрагмента информации. Именно для этого и используется блокирование. Очень важно понять, что способов блокирования в базе данных столько же, сколько и СУБД. Богатый опыт работы с моделью блокирования конкретной реляционной СУБД еще не означает, что вы знаете о блокировании все. Я, например, прежде чем начать работать с Oracle, использовал другие СУБД, в частности Sybase и Informix. В упомянутых СУБД для управления одновременным доступом применялись механизмы блокирования, но между их реализацией в каждой из СУБД имеются глубокие и фундаментальные различия. Чтобы продемонстрировать это, я кратко опишу свой путь от разработчика приложений Sybase до пользователя Informix и, наконец, разработчика приложений Oracle. Это давняя история, и поклонники Sybase скажут, что теперь в этой СУБД реализовано блокирование на уровне строк, но способ его реализации коренн1м образом отличается от используемого в Oracle. Сравнивать их - все равно, что сравнивать яблоки и апельсины, - отличия принципиальны. Программируя для Sybase, я обычно не предусматривал возможность одновременной вставки данных в таблицу несколькими пользователями, поскольку в этой СУБД подобное происходило нечасто. В то время Sybase предлагала только блокирование на уровне страниц и, поскольку данные в некластеризованных таблицах обычно вставляются в последнюю страницу, одновременной вставки данных двумя пользователями никогда не происходило. Та же проблема возникает и при попытке одновременного обновления данных (поскольку UPDATE - это фактически DELETE, за которым следует INSERT). Возможно, именно поэтому СУБД Sybase по умолчанию фиксировала или откатывала изменения сразу после выполнения каждого оператора. Кроме того, что в большинстве случаев пользователи не могли одновременно изменять ту же таблицу, при изменении таблицы заблокированными оказывались и многие запросы к таблице. Если при выполнении запроса к таблице требовалась страница, заблокированная в ходе обновления, мне приходилось ждать (иногда очень долго). Механизм блокирования был настолько неудачным, что поддержка транзакций, продолжительней тысячной доли секунды, практически отсутствовала, и при попытке их выполнения казалось, что база данных зависла. Так я приобрел множество плохих привычек. Я понял, что транзакции - это плохо , что фиксировать изменения надо быстро и никогда не удерживать блокировки данных. Одновременность работы достигалась ценой согласованности. Нужно б1ло выбирать: правильный результат или быстро полученный результат. Я пришел к выводу, что достичь одновременно и того, и другого невозможно. Когда я стал работать с СУБД Informix, дела пошли лучше, но не намного. Если я не забывал создавать таблицу с блокированием на уровне строк, мне удавалось обеспечить одновременную вставку данных в эту таблицу двумя пользователями. К сожалению, одновременная работа давалась дорого. Блокировки строк в Informix были дорогостоящими, требуя дополнительного времени и памяти. Требовалось определенное время для установки и снятия блокировок, и каждая блокировка требовала места в оперативной памяти. Кроме того, общее количество доступных системе блокировок необходимо было рассчитать до запуска СУБД. Если этого количества оказывалось достаточно, вам, можно сказать, повезло. В результате таблицы обычно создавались с блокированием на уровне страниц и, как в случае с Sybase, любая блокировка строки или страницы останавливала запросы, которым были необходимы соответствующие данные. Это приучило меня фиксировать изменения как можно быстрее. Плохие привычки, приобретенные в процессе работы с СУБД Sybase, снова пригодились, и, более того, я начал рассматривать блокировки как очень дорогой ресурс, который надо экономить. Я понял, что иногда необходимо повышать уровень блокирования вручную со строчного до табличного, чтобы избежать излишнего количества блокировок и останова системы. Начав использовать СУБД Oracle, я и не пытался читать руководства, чтобы понять, как в ней работает механизм блокирования. Используя СУБД достаточно долго и считаясь своего рода экспертом в этой области (кроме Sybase и Informix, я работал с СУБД Ingress, DB2, Gupta SQLBase и с множеством других баз данных), я стал жертвой собственной самоуверенности. Казалось, что, поскольку я знаю, как все должно работать, именно так оно и будет работать. Я очень сильно ошибался. Насколько сильно я ошибался, стало понятно в ходе тестирования производительности. На раннем этапе развития упомянутых СУБД среди их производителей было принято организовывать сравнительные тесты для крупных проектов, чтобы клиент понял, какая СУБД позволит справиться с задачей быстрее, более простым способом и предоставит больше возможностей. Было устроено сравнение СУБД Informix, Sybase и Oracle. СУБД Oracle тестировалась первой. Технические специалисты компании прибыли к нам, прочитали спецификации теста и начали настройку среды. Первое, что я заметил, - это их намерение использовать для записи времени выполнения тестовых задач таблицу базы данных, хотя предполагалось несколько десятков сеансов, в каждом из которых требовалось часто вставлять и изменять данные в этой таблице. Более того, они собирались еще и читать данные из этой таблицы в ходе выполнения теста! Отозвав одного из специалистов в сторонку, я спросил, не сошли ли они все с ума: зачем намеренно вносить еще одну потенциальную точку конфликтов в систему? Не выстроятся ли все процессы, участвующие в тесте, в очередь при работе с этой таблицей? Не исказим ли мы существенно результаты теста, пытаясь читать из этой таблицы в то время как другие процессы интенсивно вносят в нее изменения? Зачем вы хотите добавить все эти дополнительные блокировки, которыми системе придется управлять? У меня были десятки вопросов в стиле а зачем вообще так делать . До тех пор пока я не подключил- ся к Sybase или Informix и не показал, что происходит, когда два сеанса пытаются вставить данные в одну и ту же таблицу или кто-то пытается выполнить запрос к таблице, в которую другие сеансы вставляют строки (запрос возвращал ноль строк в секунду), специалистам Oracle казалось, что я несколько преувеличиваю проблемы. Разница между тем, как это делается в Oracle и в других СУБД, - феноменальна. Не стоит и говорить, что ни Informix, ни Sybase не пытались регистрировать результаты в базе данных в ходе тестирования. Они предпочли записывать результаты в обычные файлы операционной системы. Из этой истории можно сделать два вывода: все СУБД существенно различаются, и при разработке приложения необходимо подходить к каждой СУБД так, будто она для вас - первая. То, что принято делать в одной СУБД, может оказаться ненужным или просто не работать в другой. Работая с Oracle, вы поймете, что: Транзакции - это хорошо, именно для их поддержки и создавались СУБД. Откладывать фиксацию транзакции можно настолько, насколько необходимо. Не надо стремиться к коротким транзакциям с целью снижения нагрузки на систему, поскольку длинные или большие по объему изменений транзакции не нагружают систему. Правило следующее: фиксируйте транзакцию тогда, когда это необходимо, и не раньше. Размер транзакций диктуется только бизнес-логикой. Удерживать блокировки данн1х можно столько, сколько необходимо. Для вас это - средство, а не проблема, которой надо избегать. Блокировки не являются ограниченным ресурсом. Блокирование на уровне строк в Oracle не приводит к дополнительным расходам ресурсов. Никогда не нужно повышать уровень блокировки (например, блокировать таблицу вместо блокирования строк), поскольку так лучше для системы . В Oracle для системы так лучше не будет: ресурсы при этом не экономятся. Одновременный доступ к данным и их согласованность не противоречат друг другу. Всегда можно получить результаты быстро, и при том корректные. В последующих разделах главы эти утверждения будут рассмотрены более подробно. Проблемы блокирования Прежде чем описывать различные типы блокировок, используемые СУБД Oracle, имеет смысл разобраться с рядом проблем блокирования, многие из которых возникают из-за неправильно спроектированных приложений, некорректно использующих (или вообще не использующих) механизмы блокирования базы данных. Потерянные изменения Потерянное изменение - классическая проблема баз данных. Если коротко, потерянное изменение возникает, когда происходят следующие события (в указанном порядке).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |