У меня есть система, настроенная на блокировку определенного контента в таблице базы данных, чтобы только один пользователь мог редактировать этот контент одновременно. Достаточно просто, и эта часть работает нормально. Но теперь я на пути к тому, как отправить запрос на «разблокировку» контента. У меня есть хранимая процедура для разблокировки содержимого, но как/где ее вызывать, когда пользователь просто закрывает свой браузер?
Сделать последний вызов базы данных, когда пользователь покидает веб-сайт (ASPX)?
Ответы (6)
Вы также не можете знать, когда пользователь выключает свой компьютер. Вы должны сделать это наоборот.
Требовать, чтобы замок периодически обновлялся. Только веб-сайт будет делать периодическое обновление. Если пользователь прекращает использовать веб-сайт, срок действия блокировки истекает.
В противном случае требуется, чтобы пользователь явно разблокировал содержимое. Другие пользователи, которые хотят отредактировать контент, могут кричать на первого пользователя, когда тот не может выполнять свою работу. Не технологичное решение, но все же хорошее. Стыд работает.
Лучшее, что вы можете сделать, это добавить что-то в Session_End в файле global.asax. К сожалению, это не сработает, пока не истечет время сеанса.
Когда пользователь нажимает «X» в своем браузере, в любом случае нельзя гарантировать, что браузер отправит вам что-либо в ответ.
Небольшое примечание о приближении Session_End. Если вы используете этот метод, вы должны убедиться,
Это состояние сеанса - InProc, например. добавьте что-то подобное в свой Web.config
‹sessionState mode="InProc" timeout="timeout_in_minutes"/›
Убедитесь, что вы настроили IIS так, чтобы рабочие процессы не перезапускались во время нормальной работы (см., например, этот пост в блоге).
Редактировать: не напрямую отвечая на вопрос, но другим подходом может быть использование Оптимистический контроль параллелизма рассматриваемых данных.
Есть такое событие, как "пользователь закрывает браузер".
Тем не менее, я могу придумать два обходных пути:
- Используйте Javascript/Ajax для постоянного (скажем, каждые 10 секунд) вызова метода на вашей странице. DateTime вашего последнего запроса нужно где-то хранить. Теперь вы пишете службу Windows, которая каждую секунду проверяет, какой сеанс истек. Выполните свое пользовательское действие там.
- Используйте событие global.asax Session_End(). (не может использоваться с каждым SessionState, посмотрите, какие из них можно использовать)
При попытке покинуть страницу ответов stackoverflow появляется диалоговое окно «Вы уверены». Возможно, во время события выхода на странице, которое использует SO (или как бы это ни делала SO), вы можете отправить окончательный запрос с объектом XmlHttpRequest. Это не защитит, если процесс браузера неожиданно закроется (используйте для этого session_onend), но он, по крайней мере, отправит событие «Я закрыт» раньше.
Я думаю, что ваша единственная хранимая процедура может выполнять блокировку и разблокировку (используется с «Выбрать @strNewMax As NewMax»)...
Вот пример из системы, которая у меня есть:
Declare @strNewMax Char
Select @strNewMax = 'N'
BEGIN TRANSACTION
/* Lock only the rows for this Item ID, and hold those locks throughout the transaction. */
If @BidAmount > (Select Max(AB_Bid_AMT) from AuctionBid With(updlock, holdlock) Where AB_AI_ID = @AuctionItemId)
Begin
Insert Into AuctionBid (AB_AI_ID, AB_Bid_AMT, AB_Emp_ID, AB_Entry_DTM)
Select @AuctionItemId, @BidAmount, @EmployeeId, GetDate()
Select @strNewMax = 'Y'
End
COMMIT TRANSACTION
Select @strNewMax As NewMax
Это вставит запись в качестве следующей самой высокой ставки, при этом будет заблокирована вся таблица, поэтому никакие другие ставки не обрабатываются одновременно. Он вернет либо «Y», либо «N» в зависимости от того, сработало это или нет.
Может быть, вы можете взять это и настроить в соответствии с вашим приложением.