#c_sharp #sql_server
Добрый день. Имеется приложение, на C#, работающее с базой данных. У меня, как у новичка, возник вопрос, как реализовать блокировки в приложени, чтобы избежать ситуаций, когда один пользователь открывает запись, чтобы отредактировать в то время, когда она открыта у другого пользователя. Я пробовал заворачивать в одну транзакцию загрузку данных в форму и сохранение, то есть транзакция будет жить столько, сколько открыта форма редактирования. Однако, когда я попытался одновременно открыть вторую копию программы и ту же запись в ней, то SQL выдал таймаут операции. Хотелось бы, чтобы он выдавал сообщение, что запись уже открыта. Это реально сделать? Правильно ли я вообще поступаю?
Ответы
Ответ 1
Вариант пессимистичного конкурентного доступа к данным - не самый лучший, на мой взгляд лучше применить оптимистичный доступ как описано тут: https://msdn.microsoft.com/ru-ru/library/aa0416cz(v=vs.110).aspx Или как это реализовано в Entity Framework https://msdn.microsoft.com/en-us/data/jj592904.aspxОтвет 2
К сожалению, блокировки в SQL работают через ожидание - т.е. код, пытающийся поставить блокировку на уже заблокированную запись, просто ждет пока первая блокировка пройдет. Кроме того, блокировка на долгих транзакциях ненадежна, т.к. обрыв соединения с приложением, которое держит блокировку, приведет к откату транзакции и снятию блокировки. Вам стоит ввести явное поле вида "Кем Заблокировано", и обновлять его примерно так: UPDATE SomeTable SET LockedBy = @currentUserID WHERE SomeTableID = @idToLock AND LockedBy IS NULL и проверять количество обновленных строк. Если оно равно 1 - то блокировка успешно установлена для текущего пользователя. Если не 1 - то запись уже заблокирована кем-то. Снимать блокировку установкой LockedBy в NULL. Также стоит предусмотреть отслеживание времени установки блокировки и снятие ее по таймауту.Ответ 3
Посмотрите здесь, подробно описаны все блокировки https://m.youtube.com/watch?v=A9pvcnV7hvo
Комментариев нет:
Отправить комментарий