powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / блокировки, блокировки... нужен совет :)
11 сообщений из 11, страница 1 из 1
блокировки, блокировки... нужен совет :)
    #32020718
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
система работы с клиентами предусматривает сквозную нумерацию некоего документа (ну например договоров). К примеру в таблице CONF в поле DocLastNo хранится последний номер договора. Клиентское приложение должно прочесть этот номер, увеличить его на единицу и обновить в таблице.
-- declare @LastNo int
-- select @LastNo=DocLastNo from CONF
-- update CONF set DocLastNo=@LastNo+1
Но как быть если одновременно это пытаются сделать два клиентских приложения? Они могут взять один и тот же номер, что недопустимо.
Кто посоветует как избежать этого?
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020722
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
declare @LastNo int
begin tran
update CONF set DocLastNo=DocLastNo+1
select @LastNo=DocLastNo-1 from CONF
commit tran
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020724
Владимир Смирнов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-- select @LastNo=DocLastNo from CONF WITH (UPDLOCK) - считанные записи из CONF заблокируются до конца транзакции.
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020767
Moth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А тригером нельзя?????
ON INSERT
Update
CON
Set NUM= COALESCE(SELECT Max(Num) From Conf /*Where */)+ 1
Where ID = Inserted.ID
Правда если записи поодной.
Moth.
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020782
Владимир Смирнов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если посмотреть план выполнения даже самого простого изменения, вроде Update #T Set N = N+1, то видно, что изменения данных производятся в несколько шагов. При этом между сканированием (считыванием) таблицы и внесением изменений в многозадачной среде возможно обращение к этим данным из другого процесса. Даже если изменения производятся в триггере. Как раз для исключения накладок выборки-изменения данных разными процессами и существуют блокировки. Заданием различных уровней изоляции транзакций или опций блокировки (Locking Hints) можно разрешить/запретить другим транзакциям обращаться к данным, использованным в текущей транзакции. В том числе и к прочитаным данным. Какие и когда использовать блокировки? Это зависит от конкретных ситуаций. В данном случае у автора вопроса:
-- declare @LastNo int
-- select @LastNo=DocLastNo from CONF /* считывается значение счётчика из табл. CONF */
-- update CONF set DocLastNo=@LastNo+1 /* изменяется значение счётчика */
Очевидно, что после считывания счётчика необходимо запретить его считывать другим процессам.
Я в предыдущем ответе второпях посоветовал применить UPDLOCK, блокирующий считанное значение от изменений. Применительно к данной ситуации это неправильно. Пожалуй тут будет уместен HOLDLOCK, т.о. значение счётчика будет заблокировано до конца транзакции не только для изменений, но и для считывания, так что другие процессы, пытающиеся узнать значение счётчика, получат его только после окончания данной транзакции. Т.е. :

-- select @LastNo=DocLastNo from CONF WITH (HOLDLOCK) /* считывается и блокируется значение счётчика */
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020783
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а если

declare @LastNo int
begin tran
select @LastNo=DocLastNo from CONF WITH (UPDLOCK)
update CONF set DocLastNo=@LastNo+1
commit tran

> "считанные записи из CONF заблокируются до конца транзакции"

1) Т.е. после выборки можно смело делать апдейт и быть уверенным, что в промежуток select-update другое клиентское приложение не смогло ни прочитать ни обновить запись?
2) А "WITH (UPDLOCK)" не заблокирует ли последующую инструкцию
update CONF set DocLastNo=@LastNo+1
или на операторы в пределах той же транзакции это не распространяется?
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020788
olden69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2Владимир Смирнов & 2All
Благодарю, все понятно.
Весьма признателен
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32020984
xxxxxxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нужен и UPDLOCK и HOLDLOCK одновременно иначе без холдлока блокировка сразу прекратит свое существование и до конца транзакции удерживаться не будета,а без апдлока появится зависимость от уровня изоляции транзакций.
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32021014
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я препочитаю использовать блокировки только в самом крайнем случае. Кроме модификации бывает нужно еще и чтение, и это случается гораздо чаще. Я бы завел дополнительную колонку типа Timestamp и использовал бы ее по назначению (см. BOL). А в хранимой процедуре, которая производит модификацию, проверил бы @@RowCount сразу после операции модификации и если эта переменная равна нулю, выдал бы ругательство о том, что пока юзер шевелил кнопками, его успел кто-то опередить.
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32021067
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эк сколько насоветовали

Хотя совершенно рабочий вариант предложил alexeyvg, все будет работать, причем работать быстро и никому не мешать
2 olden69 используйте этот вариант, не пожалеете
...
Рейтинг: 0 / 0
блокировки, блокировки... нужен совет :)
    #32021459
Sergey+Melnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно даже без объявления транзакции Sql её сам откроет и закроет

declare @LastNo int

update CONF
set @LastNo=DocLastNo, --- взяли номер до инкремента
DocLastNo=NocLastNo+1 --- тут же увеличили его. И все обним запросом.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / блокировки, блокировки... нужен совет :)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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