SELECT_statement FOR UPDATE [of column_list] [NOWAIT]

Соберем в одной куче заметке информацию о т.н. «защите данных» в таблицах, а именно их блокировке для обычных SELECT-запросов.

Официальное определение явления с download.oracle.com/docs: Вы можете переопределить стандартную блокировку с помощью оператора SELECT который включает предложение FOR UPDATE. Этот оператор производит эксклюзивную блокировку выбранных строк (также как это делает оператор UPDATE), в ожидании обновления выбранных строк в следующем операторе.

Немного теории с firststeps.ru:

Так как обычный запрос с помощью оператора SELECT, при выполнении получает строки таблицы и при этом сама таблица выборки не блокируется, то есть любой другой пользователь может выполнить запрос к той же таблице, получив при этом данные. В Oracle при выполнении запроса, т.е. при извлечении активного набора SELECT, производится моментальный снимок таблицы (snapshot), при этом все изменения сделанные до этого момента кем-либо еще отражаются в данном наборе. А, после того как snapshot получен все изменения, произведенные в данной таблице выборке, даже если они зафиксированы оператором COMMIT, отражаться не будут!!! Для того, чтобы их отразить нужно закрыть и снова открыть курсор, загрузив данные заново! Это и есть алгоритм согласованного чтения данных, о котором я уже упоминал ранее. А вот когда мы объявляем FOR UPDATE – строки активного набора данных блокируются до момента выполнения COMMIT. Таким образом мы запрещаем изменение данных другим сеансам. Если какой-либо сеанс уже блокировал строки, то следующий SELECT FOR UPDATE, будет ждать снятия блокировки. В этом случае можно применить NOWAIT (без ожидания). Если обратиться к заблокированным строкам получим сообщение об ошибке ORA-54. Вот таким образом это работает.

Примеры
Синтаксис:

CURSOR cursor_name
IS
   select_statement
   FOR UPDATE [OF column_list] [NOWAIT];

Использование:

CURSOR c1
IS
   SELECT course_number, instructor
   FROM courses_tbl
   FOR UPDATE OF instructor;

Оставить комментарий