Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Обозначить заблокированную запись.  [new]
Ramzay_
Member

Откуда:
Сообщений: 96
Задача такая. Есть таблица, с которой одновременно могут работать несколько человек с помощью приложения.
Приложение позволяет изменять записи таблицы или просто их просматривать. Как избежать ситуации, что бы одновременно несколько человек не вносили изменения в одну и ту же запись?

Мне уже приходилось решать подобную задачу на SQL Anywhere. Там была спец.таблица, в которой отображались имя пользователя и его идентификационный номер сессии (число из 6 или 8 знаков). При открытии записи моей таблицы на изменение в одно из ее полей записывался этот номер из спец.таблицы для того пользователя, который открывал эту запись. Если кто-то еще пробовал открыть эту запись, то программа проверяла:
- Есть ли в поле моей таблицы какой-либо номер?
- Если номер присутствовал, то проверялось есть ли в спец.таблице пользователь с таким номером сессии?
- Если да, то тому, кто открывал запись выдавалось сообщение, что запись занята (и предлагалось только смотреть на нее)

Как можно подобный алгоритм реализовать на MS SQL?
1 май 15, 12:35    [17590861]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
yaxta
Member

Откуда: азербайджан,баку
Сообщений: 518
Ramzay_
Задача такая. Есть таблица, с которой одновременно могут работать несколько человек с помощью приложения.
Приложение позволяет изменять записи таблицы или просто их просматривать. Как избежать ситуации, что бы одновременно несколько человек не вносили изменения в одну и ту же запись?

Мне уже приходилось решать подобную задачу на SQL Anywhere. Там была спец.таблица, в которой отображались имя пользователя и его идентификационный номер сессии (число из 6 или 8 знаков). При открытии записи моей таблицы на изменение в одно из ее полей записывался этот номер из спец.таблицы для того пользователя, который открывал эту запись. Если кто-то еще пробовал открыть эту запись, то программа проверяла:
- Есть ли в поле моей таблицы какой-либо номер?
- Если номер присутствовал, то проверялось есть ли в спец.таблице пользователь с таким номером сессии?
- Если да, то тому, кто открывал запись выдавалось сообщение, что запись занята (и предлагалось только смотреть на нее)

Как можно подобный алгоритм реализовать на MS SQL?



а вы в первый раз в на MS SQL?
1 май 15, 13:07    [17590909]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Ramzay_
Member

Откуда:
Сообщений: 96
В кнессете на повестку дня поставили : "Можно ли отвечать вопросом на вопрос?"
Резолюция: "А почему бы и нет?"

Если можно, ближе к теме.
1 май 15, 14:25    [17591042]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Ramzay_,

ближе к теме
1 май 15, 16:33    [17591276]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8834
Ramzay_
Как можно подобный алгоритм реализовать на MS SQL?


Никак, сиквел так не работает. Он всем предоставляет равные возможности.
1 май 15, 17:58    [17591549]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Glory
Member

Откуда:
Сообщений: 104751
Ramzay_
Как можно подобный алгоритм реализовать на MS SQL?

реализовывайте, кто же вам запретит
Или вы спрашиваете, не сделает ли все это сервер за вас ?
1 май 15, 19:08    [17591751]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Сид
Member

Откуда: Москва
Сообщений: 305
Ramzay_,

Идея обречена на провал. Пользователь открывает запись на редактирование и аварийно завершает работу с программой. Теперь запись заблокирована навсегда.
Проще использовать колонку rowversion и проверять при сохранении.
Если rowversion изменился в период между открытием записи на редактирование и нажатием на кнопку Сохранить, отменяем сохранение и говорим, что другой юзер вснес изменения. А дальше уже действуем по своемс вкусу.
2 май 15, 16:32    [17594386]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Может, sp_getapplock (Transact-SQL) как-то поможет?
2 май 15, 17:16    [17594484]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Ramzay_
Member

Откуда:
Сообщений: 96
Понятно, основная идея ответов yaxta, iap, Владислав Колосов и Glory сводится к тому что я придурок.
Следовательно, у меня к ним предложение: уйти с этого форума и никогда больше не появляться ни на этом форуме, ни на каких-либо других.

Сид и iap, вам спасибо.

Сид, над твоей идеей я уже думал. Она легко реализуема. Более того, я работал с программами, которые использует твой принцип. Но есть недостаток: возможно, придется огорчать пользователей после того как они длительное время редактировали запись.

iap, к сожалению, я не увидел, как с помощью sp_getapplock можно заблокировать запись.

Я нашел выход: Есть системная таблица master..sysprocesses. У этой таблицы есть поле spid - идентификатор соединения, который присваивается пользователю при соединении с базой. Правда, этот spid может повторяться, например, если пользователь отсоединился, а вместо него присоединился кто-то другой. Но, к счастью, в этой же таблице есть поле login_time. Есть так же системная переменная @@spid, в которой хранится номер текущего соединения.

Дальше, надеюсь, все понятно.

В пользовательской таблице вводим два поля: spid и login_time, в которые при открытии записи на редактирование заносим данные из @@spid и (select login_time from master..sysprocesses where spid=@@spid).

Если эти два поля заполнены - значит запись заблокирована. Но приложение может зависнуть и эти два поля останутся заполненными навсегда. Поэтому, при проверке на блокировку нужно проверить равенство полей spid и login_time в пользовательской таблице и таблице master..sysprocesses. Если они совпадают, то запись заблокирована, если нет, то запись можно открывать и заполнять поля spid и login_time новыми значениями.
4 май 15, 07:25    [17597149]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Glory
Member

Откуда:
Сообщений: 104751
Ramzay_
Понятно, основная идея ответов yaxta, iap, Владислав Колосов и Glory сводится к тому что я придурок.

Ну если вы так себя оцениваете, то кто же вам станет возражать
4 май 15, 08:27    [17597219]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Павел-П
Member

Откуда:
Сообщений: 234
Glory
Ramzay_
Понятно, основная идея ответов yaxta, iap, Владислав Колосов и Glory сводится к тому что я придурок.

Ну если вы так себя оцениваете, то кто же вам станет возражать


Вообще-то странно Glory, во многих таких случаях вы действительно возражаете :-)
9 май 15, 10:21    [17621445]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Glory
Member

Откуда:
Сообщений: 104751
Павел-П
Glory
пропущено...

Ну если вы так себя оцениваете, то кто же вам станет возражать


Вообще-то странно Glory, во многих таких случаях вы действительно возражаете :-)

Вы тоже хотите что-то сообщить о себе ?
11 май 15, 08:39    [17624807]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Dzianis
Member

Откуда:
Сообщений: 81
Ramzay_
Я нашел выход: Есть системная таблица master..sysprocesses. У этой таблицы есть поле spid - идентификатор соединения, который присваивается пользователю при соединении с базой. Правда, этот spid может повторяться, например, если пользователь отсоединился, а вместо него присоединился кто-то другой. Но, к счастью, в этой же таблице есть поле login_time. Есть так же системная переменная @@spid, в которой хранится номер текущего соединения.

Дальше, надеюсь, все понятно.

В пользовательской таблице вводим два поля: spid и login_time, в которые при открытии записи на редактирование заносим данные из @@spid и (select login_time from master..sysprocesses where spid=@@spid).


Тык через @@spid если хочется можно контролировать коннект, но не 1ну конкретную запись в одной конкретной таблице.
11 май 15, 15:56    [17625570]     Ответить | Цитировать Сообщить модератору
 Re: Обозначить заблокированную запись.  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Ramzay_
Если эти два поля заполнены - значит запись заблокирована. Но приложение может зависнуть и эти два поля останутся заполненными навсегда. Поэтому, при проверке на блокировку нужно проверить равенство полей spid и login_time в пользовательской таблице и таблице master..sysprocesses. Если они совпадают, то запись заблокирована, если нет, то запись можно открывать и заполнять поля spid и login_time новыми значениями.
А еще пользователь может открыть запись на редактирование и уйти ... в отпуск
11 май 15, 22:56    [17626681]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить