Oracle для профессионалов



              

Реализация блокирования - часть 2


  • Сеанс записи данных блокируется, только если другой сеанс записи уже заблокировал строку, которую предполагается изменять. Сеанс считывания данных никогда не блокирует сеанс записи.
  • Эти факты необходимо учитывать при разработке приложений, однако следует помнить, что эти принципы используются только в Oracle. Разработчик, не понимающий, как используемая СУБД обеспечивает одновременный доступ, неизбежно столкнется с проблемами целостности данных (особенно часто это происходит, когда разработчик переходит с другой СУБД на Oracle, или наоборот, и не учитывает в приложении различия механизмов обеспечения одновременного доступа).

    Один из побочных эффектов принятого в СУБД Oracle "неблокирующего" подхода состоит в том, что если действительно необходимо обеспечить доступ к строке не более чем одного пользователя в каждый момент времени, то именно разработчику необходимо предпринять для этого определенные усилия. Рассмотрим следующий пример. Один разработчик показывал мне только что завершенную им программу планирования ресурсов (учебных классов, проекторов и т.д.), находящуюся в стадии внедрения. Это приложение реализовало бизнес-правило, предотвращающее выделение ресурса более чем одному лицу на любой период времени. То есть, приложение содержало специальный код, который проверял, что никто из пользователей не затребовал ресурс на тот же период времени (по крайней мере разработчик думал, что его код это проверяет). Код обращался к таблице планов и, если в ней не было строк с перекрывающимся временным интервалом, вставлял в нее новую строку. Итак, разработчик просто работал с парой таблиц:

    create table resources ( resource_name varchar2(25) primary key, ... ); create table schedules ( resource_name varchar2(25) references resources, start_time date, end_time date );

    И прежде чем зарезервировать на определенный период, скажем, учебный класс, приложение выполняло запрос вида:

    select count(*) from schedules where resource_name = :room_name and (start_time between :new_start_time and :new_end_time or end_time between :new_start_time and :new_end_time)




    Содержание  Назад  Вперед