7.5.8.2 Чтение с блокировкой
7.5.8.2 Чтение с блокировкой
В некоторых случаях использовать согласованное чтение нецелесообразно.
Приведем пример. Допустим, что необходимо добавить новую строку в таблицу
CHILD, предварительно убедившись, что для нее имеется родительская строка
в таблице PARENT.
Предположим, что для чтения таблицы PARENT было использовано согласованное
чтение, и в таблице была обнаружена родительская строка. Можно ли теперь
безопасно добавить дочернюю строку в таблицу CHILD? Нет, потому что в это
время другой пользователь мог без вашего ведома удалить родительскую
строку из таблицы PARENT.
В данной ситуации необходимо выполнить операцию SELECT в режиме
блокировки, LOCK IN SHARE MODE.
SELECT * FROM PARENT WHERE NAME = 'Jones' LOCK IN SHARE MODE;
Выполнение чтения в режиме совместного использования (share mode)
означает, что считываются самые новые доступные данные и производится
блокировка строк, чтение которых осуществляется. Если последние данные
принадлежат еще не зафиксированной транзакции, мы ждем, пока транзакция
не будет зафиксирована. Блокировка в режиме совместного использования не
позволяет другим пользователям обновить или удалить читаемую строку. После
того, как указанный выше запрос вернет родительскую строку 'Jones', мы
можем безопасно добавить дочернюю строку в таблицу CHILD и зафиксировать
транзакцию. В этом примере показано, как использовать целостность
ссылочных данных в своей программе.
Рассмотрим еще один пример. Пусть у нас есть поле целочисленного счетчика
в таблице CHILD_CODES, которое мы используем для назначения уникального
идентификатора каждой дочерней записи, добавляемой к таблице CHILD.
Очевидно, что использование согласованного чтения или чтения в режиме
совместного доступа для получения текущего значения счетчика не подходит,
так как два пользователя базы данных могут получить одно и то же значение
счетчика и создать дублирующиеся ключи при добавлении двух дочерних
записей в таблицу.
Для этого случая возможны два способа произвести чтение и увеличить
значение счетчика: (1) сначала обновить значение счетчика, увеличив его на
1, и только после этого прочитать его или (2) сначала прочитать счетчик в
режиме блокировки FOR UPDATE, а после этого увеличить его значение:
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE;
UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;
Оператор SELECT ... FOR UPDATE прочитает последние доступные данные с
установкой отдельной блокировки на каждую считываемую строку. Таким
образом, блокировка на строки устанавливается точно так же, как и в случае
поиска по UPDATE.
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий
|