powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Как заблокировать только первую запись из селекта?
19 сообщений из 19, страница 1 из 1
Как заблокировать только первую запись из селекта?
    #33834028
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задача выполнить SELECT FOR UPDATE (в терминах Oracle) и желательно заблокировать только одну первую запись.
Текущим результатом работы моей подкорки являеться вот такой SQL. Нужна критика и рекомендации

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select * from 
  (
  select 
    rownumber() over(ORDER BY START_DATE DESC) as rownumber_, 
    position.* FROM ACCOUNT_POSITION position 
  WHERE TYPE <> 'ASOF' ORDER BY START_DATE DESC 
  ) as p 
where rownumber_ <=  1  
FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS

P.S. Где в документации (раздел) описаны функции rownumber() и over()?
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33834050
Nikolay Kulikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У тебя при уровне Cursor Stability будет заблокирована после первого fetch next
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33834058
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что-н. про ограничение result set-а?

P.S. Почему то без USE AND KEEP UPDATE LOCKS "другая" транзакция стреляет SQLCODE: 911 что есть deadlock. Т.е. та другая не приостанавливаеться на SELECT-е, а идет дальше
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33834986
ппм
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ничего не понятно - выполняется селект одной строки, и спрашивается, как в result set из одной строки заблокировать только первую запись.........
А второй вопрос так вообще просто песня по понятливости..........
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33835316
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim RagozinP.S. Почему то без USE AND KEEP UPDATE LOCKS "другая" транзакция стреляет SQLCODE: 911 что есть deadlock. Т.е. та другая не приостанавливаеться на SELECT-е, а идет дальше
Т.е. вы используете вышеприведенный select с опцией for read only with rs и получаете SQLCODE -911, если запускаете этот селект одновременно из разных соединений?
Такого не может быть.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836553
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinstein
Т.е. вы используете вышеприведенный select с опцией for read only with rs и получаете SQLCODE -911, если запускаете этот селект одновременно из разных соединений?
Такого не может быть.
Нет конечно. За вышеуказанным SELECT следует UPDATE выбранной записи. 911 получаеться когда вся транзакция commit-иться.

Еще раз, при выполнении из двух потоков (threads), без USE AND KEEP UPDATE LOCKS первый SELECT и следующий UPDATE будет выполнен сразу в двух транзакциях и только при commit один из потоков получит 911 ошибку. При наличии UPDATE LOCKS, вторая транзакция остановиться на SELECT и будет ждать когда выполниться COMMIT первой.
Для полноты картины скажу что у меня на Сonnection to DB TX ISLN LVL set to RR or RS

Кстати вот текущая версия этого select

Код: plaintext
1.
2.
3.
4.
5.
6.
select * from 
  (select rownumber() over(ORDER BY START_DATE DESC) as rownumber_, 
  position.* FROM ACCOUNT_POSITION position 
    WHERE START_DATE < :date AND ACCOUNT_ID = :accountID AND PRODUCT_ID = :productID AND TYPE <> 'ASOF' 
    ORDER BY START_DATE DESC ) as p 
where rownumber_ <=  1  OPTIMIZE FOR  1  ROW 
WITH RS USE AND KEEP UPDATE LOCKS
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836758
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос можно?....
А зачем в обоих сессиях совершать какие-то телодвижения, если одна из сессий все равно откатится?....
Честно говоря из всего того что вы тут понаписали - нифига не понятно...
И зачем делать select перед update?.... можно и без этого лишнего движения обойтись...
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836771
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gardenmanВопрос можно?....
А зачем в обоих сессиях совершать какие-то телодвижения, если одна из сессий все равно откатится?....
Честно говоря из всего того что вы тут понаписали - нифига не понятно...
И зачем делать select перед update?.... можно и без этого лишнего движения обойтись...
Делаеться SELECT данные уходят наверх (Java) на их основе там делаються вычесления (упрощенно qty=qty+1, потом делаеться UPDATE на новые значения.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836827
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim RagozinЗа вышеуказанным SELECT следует UPDATE выбранной записи. 911 получаеться когда вся транзакция commit-иться.
-911 на операции commit в DB2?
Это очень странно, ИМХО такого просто не может быть.
-911 вы можете получить на select или update, но не на commit.
Что у вас за версия DB2?
Какой reason code у ошибки?
Есть ли индексы?
Если v8, то какого типа?

По коду:
Код: plaintext
ORDER BY START_DATE DESC
можно не делать и вместо <=1 лучше =1
и что, это требование приложения такое, блокировать все строки
Код: plaintext
WHERE START_DATE < :date AND ACCOUNT_ID = :accountID AND PRODUCT_ID = :productID AND TYPE <> 'ASOF'
перед последующим update, а не только ту, которая, собственно, обновляться будет?
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836867
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinstein
По коду:
Код: plaintext
ORDER BY START_DATE DESC


Собственно это мне и надо заблокировать для последующего update-а последнюю из отсортированных по дате записей. В двух словах что я делаею так это сортирую по дате и выбираю most recent/первую.

Mark Barinstein
и что, это требование приложения такое, блокировать все строки
Код: plaintext
WHERE START_DATE < :date AND ACCOUNT_ID = :accountID AND PRODUCT_ID = :productID AND TYPE <> 'ASOF'
перед последующим update, а не только ту, которая, собственно, обновляться будет?

Собственно вопрос из приведенного выше SQL будет ли блокироваться все рекордс (внутренний SELECT position) или только одна (where rownumber_ <= 1)?
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33836932
Nikolay Kulikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С уровнем изоляции СS блокируется одна строка
С уровнем изоляции RS блокируются все извлеченные строки.

Ошибка 911 имеет reason code, который позволяет определить что у тебя произовшло deadlock reason code 2
lock timeout resson code 68

Так что сначало надо посмотреть на
db2 get db cfg for DBASE | grep locktimeout
или что у тебя на уровне приложения выставлено.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33837031
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Nikolay KulikovС уровнем изоляции СS блокируется одна строка
С уровнем изоляции RS блокируются все извлеченные строки.

Это такая фича DB2 что блокировать то она блокирует, но вот узнаю я о том что что-то не так только при коммите? Пока только WITH RS/RR USE AND KEEP UPDATE LOCKS работает как мне надо, т.е приостанавливает другой select до освобождения записи.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33837238
ппм
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да просто не дает наложить блокировку, и вторая транзакция замирает на время timeout.
А вообще-то какой вопрос - ткой ответ.
Дикая ветка по понятливости.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33837365
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim RagozinСобственно это мне и надо заблокировать для последующего update-а последнюю из отсортированных по дате записей. В двух словах что я делаею так это сортирую по дате и выбираю most recent/первую.
rownumber нумерует строки в порядке, указанном в over.
Ей абсолютно все равно, что указано в ORDER BY селекта, в котором она используется.
В ORDER BY сабселекта в вашем случае вы можете указать что угодно, результат от этого не изменится.
А вообще я бы сделал так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
DECLARE C1 CURSOR FOR
select position.* 
FROM ACCOUNT_POSITION position 
WHERE START_DATE < CAST(? AS DATE) AND ACCOUNT_ID = CAST(? AS INT) AND PRODUCT_ID = CAST(? AS INT) AND TYPE <> 'ASOF' 
ORDER BY START_DATE DESC
FOR READ ONLY
OPTIMIZE FOR  1  ROW
WITH CS;
--(или RS, если надо блокировать всю выборку)
OPEN C1 USING dateV, accountID, productID;
FETCH С1 INTO ...;
--тут передача жабе
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33837431
Nikolay Kulikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты объясняешь, что у тебя за проблема и эта проблема потому, что DB2 работает не так как Oracle. Объясни целиком чего ты хочешь достичь. Возможно это можно решить другим эквивалентным образом.

Опять же не факт что у тебя deadlock'ки
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33838171
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще маленькое уточнение...
если вы юзаете select with cs то нужно это делать в курсоре, причем обязательно!.. В противном случае после селекта блокировка снимется и тогда другой юзер - делай что хошь.
Если правильно подходить, то не нужен никакой RS или RR. Нужно всего лишь:
DECLARE CURSOR С1... FOR SELECT ... FOR UPDATE ... WITH CS
OPEN С1
FETCH C1 INTO... -- строка заблокируется
-- делаем всякие вычисления и т.к. строка не нужна пропускаем ее
FETCH C1 INTO... -- блокировка предыдущей строки снимется, а новая строка заблокируется
-- делаем всякие вычисления и если строка нам пожходит
UPDATE ... WHERE CURRENT OF C1 -- обновленная строка будет блокирована до тех пор, пока не закоммитим или не откатим транзакцию
COMMIT - снимем блокировки.
Вот и всё. Нафиг не нужен RR/RS...
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33839299
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinsteinrownumber нумерует строки в порядке, указанном в over.
Ей абсолютно все равно, что указано в ORDER BY селекта, в котором она используется.
В ORDER BY сабселекта в вашем случае вы можете указать что угодно, результат от этого не изменится.

А где найти описание этой over() в документации? В каком хоть разделе? Search ничего не выдаёт.
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp

Mark Barinstein
А вообще я бы сделал так:

Все вызовы делаються через JDBC, точнее Hibernate 3.2 и JDBC. Курсоры мне не доступны, точно как и CS как Isolation Level (в JDBC эквивалента нет). Stop Proc - зло :)
Поэтому, похоже что выбрать последнюю запись с автоматической её блокировкой не судьба. Work around будет выбор последней без блокировки, потом следующим селектом блокировка записи (ID я уже буду знать), ну и последующий update.
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33839409
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim RagozinВсе вызовы делаються через JDBC, точнее Hibernate 3.2 и JDBC. Курсоры мне не доступны, точно как и CS как Isolation Level (в JDBC эквивалента нет).
Я не знаком с Hibernate.
А что, я там не могу явно указать текст запроса, как обычно в яве:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
import java.sql.*;
...
Connection con = DriverManager.getConnection(...);
PreparedStatement pst = con.prepareStatement("select ... order by ... for update with cs");
...
ResultSet rs = pst.executeQuery();
rs.next();
// do something useful
rs.close();
Оно (Hibername) не позволяет напрямую работать с ResultSet?
Connection.TRANSACTION_READ_COMMITTED - эквивалент CS.
Про OLAP functions
http://publib.boulder.ibm.com/infocenter/db2luw/v8//topic/com.ibm.db2.udb.doc/admin/r0000736.htm#olapfunc
...
Рейтинг: 0 / 0
Как заблокировать только первую запись из селекта?
    #33839786
Maxim Ragozin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark BarinsteinПро OLAP functions
http://publib.boulder.ibm.com/infocenter/db2luw/v8//topic/com.ibm.db2.udb.doc/admin/r0000736.htm#olapfunc
Вон они куда это всё засунули - спасибо.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Как заблокировать только первую запись из селекта?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]