Обозначить заблокированную запись.

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

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

Как можно подобный алгоритм реализовать на MS SQL?
yaxta
Дата: 01.05.2015 13:07:08
Ramzay_
Задача такая. Есть таблица, с которой одновременно могут работать несколько человек с помощью приложения.
Приложение позволяет изменять записи таблицы или просто их просматривать. Как избежать ситуации, что бы одновременно несколько человек не вносили изменения в одну и ту же запись?

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

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



а вы в первый раз в на MS SQL?
Ramzay_
Дата: 01.05.2015 14:25:38
В кнессете на повестку дня поставили : "Можно ли отвечать вопросом на вопрос?"
Резолюция: "А почему бы и нет?"

Если можно, ближе к теме.
iap
Дата: 01.05.2015 16:33:54
Владислав Колосов
Дата: 01.05.2015 17:58:50
Ramzay_
Как можно подобный алгоритм реализовать на MS SQL?


Никак, сиквел так не работает. Он всем предоставляет равные возможности.
Glory
Дата: 01.05.2015 19:08:55
Ramzay_
Как можно подобный алгоритм реализовать на MS SQL?

реализовывайте, кто же вам запретит
Или вы спрашиваете, не сделает ли все это сервер за вас ?
Сид
Дата: 02.05.2015 16:32:19
Ramzay_,

Идея обречена на провал. Пользователь открывает запись на редактирование и аварийно завершает работу с программой. Теперь запись заблокирована навсегда.
Проще использовать колонку rowversion и проверять при сохранении.
Если rowversion изменился в период между открытием записи на редактирование и нажатием на кнопку Сохранить, отменяем сохранение и говорим, что другой юзер вснес изменения. А дальше уже действуем по своемс вкусу.
iap
Дата: 02.05.2015 17:16:20
Может, sp_getapplock (Transact-SQL) как-то поможет?
Ramzay_
Дата: 04.05.2015 07:25:20
Понятно, основная идея ответов 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 новыми значениями.
Glory
Дата: 04.05.2015 08:27:12
Ramzay_
Понятно, основная идея ответов yaxta, iap, Владислав Колосов и Glory сводится к тому что я придурок.

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