sp_getapplock
Эта процедура вместе с sp_releaseapplock позволяет блокировать "ресурс" механизмами блокировок MS SQL Server. Здесь "ресурс" - это любой строковой идентификатор ресурса. Сравнение ресурсов производится только на равенство и поэтому чтобы заблокировать диапазон ресурсов, придётся блокировать каждый ресурс из диапазона. Эскалация блокировок для данного случая не проводится, поэтому памяти можно сожрать очень много. Самый типичный сценарий применения - не дать выполняться параллельно коду, который для параллельного выполнения не предназначен. В принципе можно использовать этот механизм для всяких "гибких блокировок", но тут очень легко упереться в огромное потребление памяти. У меня сейчас есть система, где диапазон блокируемых ресурсов доходит до 1е+5...1е+6 штук, так вот в пике просадка сильно заметна. Да и производительность всей этой системы не потрясает, если надо поставить такое количесвто блокировок. В принципе при помощи sys.dm_tran_locks можно посмотреть какие сейчас ресурсы и кем залочены (если имя ресурса небольшое). sp_getapplock практически незаменима когда свои блокировки надо привязать на транзакции MS SQL.
Несколько замечаний по системе блокировок.
1. Система блокировок хоть и может показать своё состояние через sys.dm_tran_locks, но внутри у неё, похоже не совсем обычная табличная структура, какая-то хитрая. Об этом косвенно свидетельствует скорость добавления блокировок и скорость их снятия.
2. Блокировки хранятся только в памяти и поэтому могут её засрать. Если это обычные блокировки, то срабатывает механизм эскалации блокировок (куча белких объединяются в крупную), но лучше до этого не доводить. А sp_getapplock не могут эскалироваться (сервер не в курсе как объединять твои ресурсы).
3. Начиная с 2005 версии MS SQL может работать не только "блокировочником", но и в "версионном" режиме (см.
READ_COMMITTED_SNAPSHOT). В принципе для большинства OLTP систем этот режим (если его правильно использовать) более предпочтителен. Меня уже подзаебали отчеты в режиме READ_UNCOMMITTED, а по другому в блокировочниках не получится.
xp_userlock
Эта процедура не видна в обычном режиме. Для того, чотбы получить select object_id(N'sys.xp_userlock') нужно подцепиться к MS SQL в
Dedicated Administrator Connection (подробнее
тут).
Этот режим позволяет видеть многие системные объекты, недоступные для простого соединения (в том числе sys.sysqnames, sys.sysobjrdb и другие). Посмотри список проверяемых объектов БД maser при помощи DBCC CHECKDB и список таблиц этой БД :)
Также этот режим нередко позволяет залогиниться на сервер, когда тот не отвечает на нормальные соединения. Лет 5 назад наталкивались на забавную ошибку 1С 8.0, когда при попытке читать журнал регистрации в некоторых случаях 1С это делала в транзакции и с блокировками. Из-за миллионов блокировок MS SQL тихо вставал раком и больше ничего не делал. Смогли продиагностировать и победить только при помощи DAC.
Ну и за счет доступа к "невидимым" объектам этот режим позволяет
обойти шифрование процедур и функций.
Вообще, в MS SQL server прямо-таки неприлично много недокументированных команд, возможностей и фич, уши которых торчат на пользовательском уровне.
Упомянутая sys.xp_userlock видна только под DAC. Это расширенная хранимая процедура, т.е. процедура реализованная в DLL. Механизм расширенных ХП достаточно древний, еще в MS SQL 6.5 был, и MS
обещает от него скоро отказаться. До MS SQL 2005 это был по сути единственный способ интеграции с MS SQL на низком уровне (если не считать убогого oa_create).
Тут мы подходим к теме ...
интеграция с .NET
MS SQL, начиная с версии 2005, может достаточно активно использовать код написаный для CLR (.NET), чем позволяет сильно расширить возможности TSQL. Можно использовать внешние скалярные функции, можно интегрироваться с другими приложениями, можно написать собственную агрегатную функцию и т.п. Подробнее в
документации. MS постаралась сделать удобный и, что немаловажно, безопасный инструмент вместо убогих, ограниченных возможностей расширенных ХП и oa_create, использование которых с точки зрения стабильности и безопасности было похоже на заколачивание гвоздей минами.