В некоторых случаях использовать
согласованное чтение
нецелесообразно. Приведем пример.
Допустим, что необходимо добавить
новую строку в таблицу
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.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.
© 1995-2005 MySQL AB. All rights reserved.
