SQL Server 2016: SESSION_CONTEXT

Немногие знают, но в SQL Server присутствует механизм, когда можно сохранять определенное состояние сессии и передавать сигналы между разными запросами в пределах одной сессии, либо использовать это как дополнительный мониторинг. Ранее я уже писал об этом. Вы можете обратиться к этой статье, чтобы прочитать об этой возможности более подробно. В этой статье я бы хотел рассказать об улучшении этого механизма, особенно, когда нужно было хранить несколько значений, т.к. появляется полноценное хранилище типа key-value.

Для установки значения теперь есть новая хранимая процедура sp_set_session_context. В качестве параметров вы передаете в нее @key – название ключа типа sysname, размером до 128 байт. Также вы передаете параметр @value – значение этого ключа типа sql_variant, размером до 8000 байт. Если вы передадите в параметр @value значение null, то это освободит ранее занимаемую этим значением память. Также имеется опциональный параметр @read_only, который по умолчанию имеет значение 0. Если вы передадите в него 1, то не сможете повторно изменить значение данного параметра. В зависимости от ситуации, это может вам пригодиться.

Ниже я привожу пример установки пары значений для сессии.

exec sp_set_session_context 'rows_per_page', 1000;
exec sp_set_session_context 'user_type', 'simple', @read_only = 1;

Приложение при соединении с базой данных может установить эти настройки, в зависимости от которых будут дальше работать различные хранимые процедуры. В данном случае, в зависимости от типа пользователя возвращать разный набор полей в отчете, а также максимальное количество строк на одну страницу. Это всего лишь один из примеров, как вы можете использовать переменные сессии.

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

select session_context(N'user_type');

А дальше вы уже можете использовать его по своему усмотрению.

Каждый пользователь может устанавливать и изменять настройки в рамках своей сессии, но есть ограничение в 256 кб на одну сессию (согласно документации). Если оно будет превышено, возникнет ошибка. Одна тест показывает, что ошибка возникает, если размер превышает 1 Мб. Так что, скорее всего, размер был расширен, но документация пока не обновлена.

Msg 15665, Level 16, State 1, Procedure sp_set_session_context, Line 1 [Batch Start Line 0]
The value was not set for key ‘125’ because the total size of keys and values in the session context would exceed the 1 MB limit.

Также с помощью системного представления sys.dm_os_memory_objects вы можете посмотреть, сколько всего памяти занято на вашем сервере переменными сессий.

select *
from sys.dm_os_memory_cache_counters
where type = 'CACHESTORE_SESSION_CONTEXT';

Как мы видим, функционал может быть полезен в различных сценариях, а улучшение действительно заметное как в плане удобства, так и в плане объема хранимых данных.