Освободить блокировку другого пользователя, полученную с помощью sp_getapplock на SQL Server - PullRequest
4 голосов
/ 28 апреля 2010

У нас есть система, которая использует sp_getapplock для создания эксклюзивного мьютекса в любое время, когда кто-то открывает заказ в графическом интерфейсе. Это используется для предотвращения одновременного внесения изменений в заказ несколькими людьми.

Иногда люди открывают заказ и уходят домой, оставляя его открытым. Это эффективно блокирует возможность вносить изменения в заказ. Затем я получаю электронные письма, звонки и в итоге делаю kill <spid> в корпоративном менеджере. Очевидно, мне это надоело, и я хочу быстро создать веб-форму самообслуживания.

Основная проблема, с которой я столкнулся, заключается в том, что kill требует привилегий sysadmin, которые я не хочу давать пользователю, от имени которого работает наш веб-сайт. Я пробовал sp_releaseapplock, но это не позволяет снять блокировку другого пользователя (даже при вызове его как системного администратора).

Итак, наконец, мой вопрос; кто-нибудь знает об альтернативном методе освобождения блокировки, полученной другим пользователем с помощью sp_getapplock?

1 Ответ

9 голосов
/ 28 апреля 2010

Документация довольно ясна по этому вопросу:

Блокировки, размещенные на ресурсе, связаны либо с текущей транзакцией, либо с текущим сеансом. Блокировки, связанные с текущей транзакцией, снимаются, когда транзакция фиксируется или откатывается. Блокировки, связанные с сеансом, снимаются при выходе из сеанса. Когда сервер по какой-либо причине отключается, все блокировки снимаются.

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

Рассматривали ли вы использование какой-либо формы оптимистического параллелизма вместо этого? Предполагается, что блокировки выполняются менее чем за секунду, то есть во время обычной транзакции. Именно по этой причине обычно не стоит держать его в течение нескольких минут (или часов).

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

Если вы не хотите давать пользователю привилегии sysadmin, вы можете создать хранимую процедуру, чтобы убить процесс WITH EXECUTE AS <admin_user> ... разумеется, имея в виду, что это открывает довольно широкую дыру в безопасности, поэтому будьте очень осторожны с теми, кому вы предоставляете разрешения на выполнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...