powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как правильно взять единственную запись в обработку?
24 сообщений из 24, страница 1 из 1
Как правильно взять единственную запись в обработку?
    #40089908
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица MS SQL, в которой, среди прочего, есть 1)уникальный идентификатор записи типа bigint 2)поле статуса записи типа int.
Приложению нужно взять из таблицы первую попавшуюся запись, у которой статус = 0 и тут же пометить её как прочитанную, поставив статус = 1, чтобы другие (параллельные конкурирующие) процессы не могли взять её повторно.
Как это лучше всего сделать, если MS SQL - 2017-й?

Решение, успешно работавшее какое-то время, стало порождать блокировки "на ровном месте", и поэтому пока не приводится.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40089914
spenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
5.
declare @i int
update top (1) #t
  set @i=i,
       j=1
  where j=0
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40089919
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
Как это лучше всего сделать
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
declare @id bigint;

update top (1) MyTable with (rowlock, readpast)
 set
  @id = id,
  status = 1
where
 status = 0;
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090012
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответы.

Вопросы.
1. Какой уровень изоляции транзакций подразумевается? Сейчас там Serializable (по причинам, которые уже никто не вспомнит).

2. Хинты реально нужны? Сейчас так: with(UPDLOCK, ROWLOCK)
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090019
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
Какой уровень изоляции транзакций подразумевается?
Будет правильно работать даже на RUC.
AR®
Хинты реально нужны?
Зависит от требований.
Readpast нужен, чтобы конкурирующие сеансы не выстраивались в очередь.
Rowlock желателен, чтобы автоматом не выбралась гранулярность блокировок уровня страницы или таблицы
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090026
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Будет правильно работать даже на RUC.

А при serializable нельзя использовать readpast...

В порядке пути к совершенству: можно ли как-то ввести сортировку, чтобы выбирался минимальный идентификатор со статусом = 0 ? Написать with (rowlock, readpast, index(подходящийИндекс)) ?
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090028
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,

при serializable вы всегда получите очередь ожиданий при случайном выборе.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090031
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
А при serializable нельзя использовать readpast...
Можно. Но для данной задачи serializable избыточен.
Если же выполняется в рамках другой задачи, где нужен serializable, добавьте еще хинт readcommittedlock.
AR®
можно ли как-то ввести сортировку, чтобы выбирался минимальный идентификатор со статусом = 0 ?
Можно
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as
(
 select top (1)
  id, status
 from
  MyTable with (rowlock, readpast)
 where
  status = 0
 order by
  id
)
update t
 set
  @id = id,
  status = 1;
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090032
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов
при serializable вы всегда получите очередь ожиданий при случайном выборе.


Возможно, именно это и имеет место. Но вот что интересно, на более ранних MS SQL (по крайней мере 2008) этого не наблюдалось.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090033
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Можно. Но для данной задачи serializable избыточен.


Сам не пробовал, но судя по документации - нельзя

https://docs.microsoft.com/ru-ru/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver15
Аргумент READPAST можно указывать только в транзакциях, выполняемых на уровнях изоляции READ COMMITTED или REPEATABLE READ.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090034
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Можно
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as
(
 select top (1)
  id, status
 from
  MyTable with (rowlock, readpast)
 where
  status = 0
 order by
  id
)
update t
 set
  @id = id,
  status = 1;



Очень близкое к этому используется и приводит к ожиданиям deadlock...
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090036
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex
Сам не пробовал, но судя по документации - нельзя


Пробовал, ошибка. А добавлять внутри "понижающий" readcommittedlock не хочу, т.к. стараюсь применить простые и устойчивые решения.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090038
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex
Сам не пробовал, но судя по документации - нельзя
Да, точно.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090039
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
Очень близкое к этому используется и приводит к ожиданиям deadlock...
Очень близкое не означает такое же.
И ожиданий deadlock не бывает. Либо deadlock, либо ожидание освобождения ресурса.
AR®
стараюсь применить простые и устойчивые решения.
Ну тогда блокируйте таблицу полностью - самое простое и устойчивое решение.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090048
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,

попробуйте выбирать случайный ID из сформированного списка, список формируйте при условии readpast. Количество коллизий должно значительно сократиться, если будете выполнять запрос по точному значению ID.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090050
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Очень близкое не означает такое же.

Это верно.
invm
И ожиданий deadlock не бывает. Либо deadlock, либо ожидание освобождения ресурса.

Не придирайтесь к словам. :)
AR®
Ну тогда блокируйте таблицу полностью - самое простое и устойчивое решение.

Когда исчерпаю другие подходы, попробую. :)
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090051
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов
AR®,

попробуйте выбирать случайный ID из сформированного списка, список формируйте при условии readpast. Количество коллизий должно значительно сократиться, если будете выполнять запрос по точному значению ID.


Это было бы хорошо, если бы список был поменьше. Но подумать в эту сторону можно.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090108
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,

берите первые сто свободных, какая вам разница.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090116
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
invm
Можно
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as
(
 select top (1)
  id, status
 from
  MyTable with (rowlock, readpast)
 where
  status = 0
 order by
  id
)
update t
 set
  @id = id,
  status = 1;



Очень близкое к этому используется и приводит к ожиданиям deadlock...


Еще один любитель "рассказывать".
Нет графа - нет дедлока.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090233
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222


Еще один любитель "рассказывать".
Нет графа - нет дедлока.


Поясните.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090250
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
aleks222


Еще один любитель "рассказывать".
Нет графа - нет дедлока.


Поясните.


Рассуждения о сферическом дедлоке в вакууме бесплодны.

У вас же, ни конкретного запроса, ни DDL таблиц и индексов, ни графа дедлока.

Балабольство в чистом виде, короче.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090333
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бывая здесь не часто, я, видимо, не всё понимаю, что происходит на форуме...
Неужели поводом к критике в мой адрес может служить единственная пропущенная мной запятая (между словами "ожиданиям" и "deadlock")?

Благодарю всех, кто ответил по существу.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090355
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®
Бывая здесь не часто, я, видимо, не всё понимаю, что происходит на форуме...
Неужели поводом к критике в мой адрес может служить единственная пропущенная мной запятая (между словами "ожиданиям" и "deadlock")?

Поводом для критики является безграмотность постановки задачи.
Но мыши могут продолжать кушать кактус.
...
Рейтинг: 0 / 0
Как правильно взять единственную запись в обработку?
    #40090384
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
Поводом для критики является безграмотность постановки задачи.

А где вообще постановка Вам задачи?
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как правильно взять единственную запись в обработку?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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