Мне не ясно, что у вас есть проблема, которую вы, кажется, думаете, что у вас есть.
Обновление строки в таблице по сути устанавливает блокировку уровня строки в этой строке. Никакой другой сеанс не может обновить эту строку, пока вы не снимите блокировку, завершив транзакцию фиксацией или откатом. После завершения транзакции другие сеансы могут перезаписать ваше обновление. Нет необходимости или пользы для блокировки строк в SELECT
.
Если вы пытаетесь написать свое приложение, чтобы избежать потерянных обновлений (то есть вы хотите, чтобы другой сеанс не обновлял те же строки, которые вы сделали после совершения транзакции, не показывая другому пользователю ваши обновленные данные в первую очередь), вашему приложению потребуется реализовать какую-то дополнительную блокировку. Наиболее эффективным было бы реализовать оптимистическую блокировку с использованием некоторого столбца LAST_UPDATE_TIMESTAMP
в таблице. Предполагая, что вы добавили этот столбец в таблицу, если у него его еще нет, вы будете выбирать LAST_UPDATE_TIMESTAMP
всякий раз, когда запрашиваете данные для представления пользователю, и вы указали бы LAST_UPDATE_TIMESTAMP
в своем UPDATE
. Если ваш UPDATE
обновил ровно 1 строку, вы знаете, что никто не изменил данные с тех пор, как вы их запросили. Если бы ваши UPDATE
обновили 0 строк, вы бы знали, что данные изменились, так как вы запросили их, и ваше приложение должно будет предпринять соответствующие действия (то есть запрос данных, повторное представление их пользователю, запрос пользователя сохранить ли внесенные изменения и т. д.).
Однако в вашем запросе есть другая проблема. SELECT
утверждение почти наверняка не делает то, что вы думаете (или намереваетесь) сделать. Этот запрос получает произвольные 10 строк из MYTABLE
, где PROCS_DT
равен NULL, а затем упорядочивает эти произвольные 10 строк.
SELECT
id
FROM mytable
WHERE
rownum<=10 and PROCS_DT is null
order by CRET_DT,PRTY desc
Предполагая, что вы действительно хотите получить "10 лучших" результатов, вам нужно будет сделать ORDER BY
в подзапросе перед применением предиката ROWNUM
, то есть
SELECT
id
FROM (SELECT *
FROM mytable
WHERE procs_dt IS NULL
ORDER BY cret_dt, prty desc)
WHERE
rownum<=10
Или вы можете использовать аналитическую функцию, т.е.
SELECT
id
FROM (SELECT m.*,
rank() over (ORDER BY cret_dt, prty desc) rnk
FROM mytable m
WHERE procs_dt IS NULL)
WHERE
rnk<=10