Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
система работы с клиентами предусматривает сквозную нумерацию некоего документа (ну например договоров). К примеру в таблице CONF в поле DocLastNo хранится последний номер договора. Клиентское приложение должно прочесть этот номер, увеличить его на единицу и обновить в таблице. -- declare @LastNo int -- select @LastNo=DocLastNo from CONF -- update CONF set DocLastNo=@LastNo+1 Но как быть если одновременно это пытаются сделать два клиентских приложения? Они могут взять один и тот же номер, что недопустимо. Кто посоветует как избежать этого? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2002, 11:32 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
declare @LastNo int begin tran update CONF set DocLastNo=DocLastNo+1 select @LastNo=DocLastNo-1 from CONF commit tran ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2002, 12:05 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
-- select @LastNo=DocLastNo from CONF WITH (UPDLOCK) - считанные записи из CONF заблокируются до конца транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2002, 12:09 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
А тригером нельзя????? ON INSERT Update CON Set NUM= COALESCE(SELECT Max(Num) From Conf /*Where */)+ 1 Where ID = Inserted.ID Правда если записи поодной. Moth. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2002, 04:33 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
Если посмотреть план выполнения даже самого простого изменения, вроде 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) /* считывается и блокируется значение счётчика */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2002, 07:32 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
а если 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 или на операторы в пределах той же транзакции это не распространяется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2002, 07:34 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
2Владимир Смирнов & 2All Благодарю, все понятно. Весьма признателен ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2002, 07:50 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
нужен и UPDLOCK и HOLDLOCK одновременно иначе без холдлока блокировка сразу прекратит свое существование и до конца транзакции удерживаться не будета,а без апдлока появится зависимость от уровня изоляции транзакций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2002, 13:16 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
А я препочитаю использовать блокировки только в самом крайнем случае. Кроме модификации бывает нужно еще и чтение, и это случается гораздо чаще. Я бы завел дополнительную колонку типа Timestamp и использовал бы ее по назначению (см. BOL). А в хранимой процедуре, которая производит модификацию, проверил бы @@RowCount сразу после операции модификации и если эта переменная равна нулю, выдал бы ругательство о том, что пока юзер шевелил кнопками, его успел кто-то опередить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2002, 18:16 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
Эк сколько насоветовали Хотя совершенно рабочий вариант предложил alexeyvg, все будет работать, причем работать быстро и никому не мешать 2 olden69 используйте этот вариант, не пожалеете ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2002, 07:52 |
|
||
|
блокировки, блокировки... нужен совет :)
|
|||
|---|---|---|---|
|
#18+
Можно даже без объявления транзакции Sql её сам откроет и закроет declare @LastNo int update CONF set @LastNo=DocLastNo, --- взяли номер до инкремента DocLastNo=NocLastNo+1 --- тут же увеличили его. И все обним запросом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2002, 15:32 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32020724&tid=1824202]: |
0ms |
get settings: |
5ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
80ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
2ms |
| others: | 237ms |
| total: | 413ms |

| 0 / 0 |
