Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Sybase ASA, ASE, IQ Новый топик    Ответить
 пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
Нужно прочитать некоторое количество записей из таблицы, и заблокировать их для других транзакций. В MSSQL для этого применяется такой код
select top 10 from table with (updlock, rowlock, nowait, readpast) where bla bla bla

приведенный набор хинтов не только блокирует записи, но и делает их невыдимыми для точно таких же запросов, вызываемых из других транзакций - они получают непересекающиееся наборы данных.
Попробовал аналог в ASE 15.7 - ничего не получается. В том числе и для каждого хинта по отдельности.
select top 10 from table with (updlock, holdlock, readpast) where bla bla bla

Incorrect sintax near keyword 'with'

Что это? Неправильный запрос или драйвер не справился? Используется jtds-1.3.1
20 июл 20, 11:41    [22170305]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
White Owl
Member

Откуда:
Сообщений: 12553
ivanra,

В ASE такой возможности нет.

И вообще, зачем такое может понадобиться?
20 июл 20, 15:35    [22170492]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
White Owl,

сценарий такой: есть буферная таблица, в которую попадают данные, и эти данные надо дальше передать, в другие системы. Для этого некий робот периодически делает запрос к данной таблице, примерно такой, как наверху. Робот работает в XA транзакции, в результате обеспечивается атомарное взаимодействие с другими системами. В простейшем случае никаких хинтов не надо, но всё осложняется тем, что для устойчивости и масштабируемости одновременно работает несколько таких роботов.
Задача в том, чтобы не было конкуренции за одни и те же записи, и не было ожиданий, пока освободятся блокировки.
Приведенный набор хинтов updlock, rowlock, nowait, readpast в MSSQL решает данную задачу.

Можно конечно пойти классическим путем: берем очередную запись и помечаем на удаление
delete from table where id=...

но тогда запись блокируется, и если параллельная транзакция сделала такую же выборку и попыталась также удалить эту запись, то ей придется ждать результатов текущей транзакции.
Поэтому хочется как в MSSQL - сразу выбирать непересекающиеся наборы.
Ну ладно, пусть они даже пересекаются, главное не ждать.
Поможет ли команда
set lock nowait
?
20 июл 20, 16:39    [22170540]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
White Owl
Member

Откуда:
Сообщений: 12553
ivanra,

Жуть какая.
Во первых, ETL делается на основе дат или чекпоинтов.
Во вторых, сначала пробуют настроить коммерческие ETL системы.
В третьих, если так сильно хочется делать мультипотоковый экстракт - ну задай разным роботам вытягивать данные из разных таблиц. Зачем их все на одну таблицу натравливать???

В общем, тебе очень сильно стоит пересмотреть подход к выгрузке данных. Очень-очень.
21 июл 20, 05:22    [22170789]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
White Owl,
я ничего этого делать не буду. Во-первых, я не разработчик БД, а интегратор. Работаю с тем, что дали на вход.
Во-вторых, это не ETL. На выходе у меня не данные, а запуск бизнес процессов. Для простоты - JMS.
И параллельность тоже не моя прихоть, а данность. Она тут в основном для отказоустойчивости и непрерывности обработки.

Вот в этих условиях надо избежать конкуренции за одни и те же записи, желательно без сериализации.
21 июл 20, 09:55    [22170847]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
В общем, добрался до базы и проверил. Без всяких хинтов работает классический шаблон
begin tran
select top 10 from table where bla bla bla
-- потом в цикле по выбранным
delete from table where id=...  -- пометили на удаление
/* и дальше передаем эту строку в другие системы. Если в этот момент работает параллельная транзакция N2
с тем же набором данных, то на этот delete она не ждет завершения текущей транзакции N1,
а сразу возвращает update_count=0, и по этому признаку с данной строкой в транзакции N2 ничего не делаем,
и переходим к следующей. */
commit tran


Медленнее, чем с хинтами (в MSSQL), которые сразу возвращают непересекающиеся наборы данных, но главное без блокировок. Блокировок записей нет -> опасность дедлока отсутствует.
21 июл 20, 11:51    [22170907]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
SELECT ... FOR UPDATE -- работает, есть везде.
27 июл 20, 10:42    [22174051]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra


Что это? Неправильный запрос или драйвер не справился? Используется jtds-1.3.1


Неправильны запрос.
27 июл 20, 10:51    [22174055]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
MasterZiv
SELECT ... FOR UPDATE -- работает, есть везде.

Увы, но речь идет о запросе с клиента. Это не курсор и не сохраненная процедура
27 июл 20, 14:11    [22174189]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra
MasterZiv
SELECT ... FOR UPDATE -- работает, есть везде.

Увы, но речь идет о запросе с клиента. Это не курсор и не сохраненная процедура


И?
12 авг 20, 14:49    [22181493]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra
В общем, добрался до базы и проверил. Без всяких хинтов работает классический шаблон
begin tran
select top 10 from table where bla bla bla
-- потом в цикле по выбранным
delete from table where id=...  -- пометили на удаление
/* и дальше передаем эту строку в другие системы. Если в этот момент работает параллельная транзакция N2
с тем же набором данных, то на этот delete она не ждет завершения текущей транзакции N1,
а сразу возвращает update_count=0, и по этому признаку с данной строкой в транзакции N2 ничего не делаем,
и переходим к следующей. */
commit tran


Медленнее, чем с хинтами (в MSSQL), которые сразу возвращают непересекающиеся наборы данных, но главное без блокировок. Блокировок записей нет -> опасность дедлока отсутствует.


Это
begin tran
select top 10 from table where bla bla bla


тебе не будет блокировать эти записи до конца транзакции.

Для этого нужно ещё добавить в SELECT фразу FOR UPDATE
12 авг 20, 14:52    [22181494]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
MasterZiv,

SELECT FOR UPDATE - это первое, что я попробовал. Сервер сообщает, что такой селект может использоваться только в объявлении курсора или в теле хранимой процедуры. Возможно, есть какие-то настройки в конфигурации сервера, открывающие возможность использования этого выражения в обычном клиентском запросе, но я уже написал выше, что мне они недоступны.
Что касается классического шаблона блокировки записи, то она достигается не селектом, а удалением. Как это работает - написано в длинном комментарии выше.
12 авг 20, 20:26    [22181631]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra
MasterZiv,

SELECT FOR UPDATE - это первое, что я попробовал. Сервер сообщает, что такой селект может использоваться только в объявлении курсора или в теле хранимой процедуры. Возможно, есть какие-то настройки в конфигурации сервера, открывающие возможность использования этого выражения в обычном клиентском запросе, но я уже написал выше, что мне они недоступны.
Что касается классического шаблона блокировки записи, то она достигается не селектом, а удалением. Как это работает - написано в длинном комментарии выше.


Чего-чего?
Ты может быть привещёшь полный текст запроса, полностью сообщение об ошибке?

Сообщение было отредактировано: 9 сен 20, 14:50
9 сен 20, 14:53    [22194244]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
ivanra
Member

Откуда:
Сообщений: 889
MasterZiv,

select top 10 from mytable for update

Error code 7305
FOR UPDATE can not be used in a SELECT which is not part of the declaration of a cursor or which is not inside a stored procedure.
14 сен 20, 13:25    [22196530]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra
MasterZiv,

select top 10 from mytable for update

Error code 7305
FOR UPDATE can not be used in a SELECT which is not part of the declaration of a cursor or which is not inside a stored procedure.


А, это да, ну так и объяви курсор, или в процедуре сделай.
Про то, что надо транзакцию открыть, наверное, не надо напоминать...
16 сен 20, 09:19    [22198091]     Ответить | Цитировать Сообщить модератору
 Re: пессимистическая блокировка  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
ivanra,

Да, и надо было наверное сразу ещё сказать про достаточно распространённый трюк -- фиктивный update нужных строк в начале транзакции. Его можно делать вместо SELECT ... FOR UPDATE
16 сен 20, 09:24    [22198096]     Ответить | Цитировать Сообщить модератору
Все форумы / Sybase ASA, ASE, IQ Ответить