Сделать последний вызов базы данных, когда пользователь покидает веб-сайт (ASPX)?

У меня есть система, настроенная на блокировку определенного контента в таблице базы данных, чтобы только один пользователь мог редактировать этот контент одновременно. Достаточно просто, и эта часть работает нормально. Но теперь я на пути к тому, как отправить запрос на «разблокировку» контента. У меня есть хранимая процедура для разблокировки содержимого, но как/где ее вызывать, когда пользователь просто закрывает свой браузер?


person MisterIsaak    schedule 12.03.2010    source источник


Ответы (6)


Вы также не можете знать, когда пользователь выключает свой компьютер. Вы должны сделать это наоборот.

Требовать, чтобы замок периодически обновлялся. Только веб-сайт будет делать периодическое обновление. Если пользователь прекращает использовать веб-сайт, срок действия блокировки истекает.

В противном случае требуется, чтобы пользователь явно разблокировал содержимое. Другие пользователи, которые хотят отредактировать контент, могут кричать на первого пользователя, когда тот не может выполнять свою работу. Не технологичное решение, но все же хорошее. Стыд работает.

person John Saunders    schedule 12.03.2010
comment
Хм. Я боялся, что это будет ответ. Я бы не волновался, но кажется, что средний IQ пользователя ниже 70 :( - person MisterIsaak; 12.03.2010
comment
@Jisaak: как я уже сказал, стыд работает. Заставьте их встать перед следующей встречей, чтобы сказать, как они блокировали работу других людей. - person John Saunders; 12.03.2010
comment
Ахахаха, я думаю, я начну копилку денег. Поэтому каждый раз, когда кто-то забывает разблокировать, ему приходится класть доллар в мою банку с деньгами. Ничто не сравнится с бесплатной едой :) - person MisterIsaak; 12.03.2010
comment
@Jisaak: на самом деле, я уверен, что есть исследования по этому поводу, но держу пари, банка с деньгами менее эффективна, чем неодобрение коллег. - person John Saunders; 12.03.2010

Лучшее, что вы можете сделать, это добавить что-то в Session_End в файле global.asax. К сожалению, это не сработает, пока не истечет время сеанса.

Когда пользователь нажимает «X» в своем браузере, в любом случае нельзя гарантировать, что браузер отправит вам что-либо в ответ.

person AaronS    schedule 12.03.2010
comment
Но независимо от того, session_end все равно будет вызываться, когда время ожидания пользователя истекает, верно? - person MisterIsaak; 12.03.2010
comment
Правильно, если что-то еще не остановит весь процесс IIS. - person AaronS; 13.03.2010

Небольшое примечание о приближении Session_End. Если вы используете этот метод, вы должны убедиться,

  1. Это состояние сеанса - InProc, например. добавьте что-то подобное в свой Web.config

    ‹sessionState mode="InProc" timeout="timeout_in_minutes"/›

  2. Убедитесь, что вы настроили IIS так, чтобы рабочие процессы не перезапускались во время нормальной работы (см., например, этот пост в блоге).

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

person Mads Ravn    schedule 12.03.2010
comment
О черт. Спасибо за внимание. Вот вам и реализация функции быстрой блокировки и приятных выходных. - person MisterIsaak; 12.03.2010
comment
Без проблем. Я сам был поражен 2. и я бы не хотел, чтобы это случилось с кем-то еще :) - person Mads Ravn; 12.03.2010

Есть такое событие, как "пользователь закрывает браузер".

Тем не менее, я могу придумать два обходных пути:

  • Используйте Javascript/Ajax для постоянного (скажем, каждые 10 секунд) вызова метода на вашей странице. DateTime вашего последнего запроса нужно где-то хранить. Теперь вы пишете службу Windows, которая каждую секунду проверяет, какой сеанс истек. Выполните свое пользовательское действие там.
  • Используйте событие global.asax Session_End(). (не может использоваться с каждым SessionState, посмотрите, какие из них можно использовать)
person citronas    schedule 12.03.2010
comment
Я бы не хотел полагаться на какое-либо событие закрытия браузера пользователем на стороне клиента для чего-либо, что влияет на сервер или других пользователей. - person AndreiM; 12.03.2010

При попытке покинуть страницу ответов stackoverflow появляется диалоговое окно «Вы уверены». Возможно, во время события выхода на странице, которое использует SO (или как бы это ни делала SO), вы можете отправить окончательный запрос с объектом XmlHttpRequest. Это не защитит, если процесс браузера неожиданно закроется (используйте для этого session_onend), но он, по крайней мере, отправит событие «Я закрыт» раньше.

person Sukasa    schedule 12.03.2010

Я думаю, что ваша единственная хранимая процедура может выполнять блокировку и разблокировку (используется с «Выбрать @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» в зависимости от того, сработало это или нет.

Может быть, вы можете взять это и настроить в соответствии с вашим приложением.

person Mikey    schedule 12.03.2010