Какова область действия CONTEXT_INFO в SQL Server? - PullRequest
23 голосов
/ 11 июня 2010

Я использую CONTEXT_INFO для передачи имени пользователя в триггер удаления для целей таблицы аудита / истории. Я пытаюсь понять сферу действия CONTEXT_INFO и создаю ли я потенциальное состояние гонки.

В каждой из моих таблиц базы данных есть сохраненный процесс для обработки удалений. Удаляемый сохраненный процесс принимает userId в качестве параметра и устанавливает CONTEXT_INFO в значение userId. Мой триггер удаления затем захватывает CONTEXT_INFO и использует его для обновления таблицы аудита, которая указывает, кто удалил строку (и).

Вопрос в том, что, если одновременно выполняются два удаления sprocs от разных пользователей, может ли CONTEXT_INFO, установленный в одном из sprocs, использоваться триггером, запущенным другим sproc?

Я видел эту статью http://msdn.microsoft.com/en-us/library/ms189252.aspx, но я не совсем понимаю объем сессий и пакетов в SQL Server, что является ключевым моментом для полезной статьи!

Я бы отправил код, но сейчас не хватает времени. Я отредактирую позже, если это не будет достаточно ясно.

Заранее спасибо за любую помощь.

Ответы [ 2 ]

30 голосов
/ 12 июня 2010

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

Если вы задали контекстную информацию в процедуре, любой триггер, впоследствии выполненный в этом сеансе, увидит вновь установленное значение контекстной информации. Установка значения идентификатора пользователя в контекстной информации, как вы предлагаете, и использование его в триггерах является типичным примером использования контекстной информации и совершенно безопасна в отношении параллелизма, поскольку в основном нет параллелизма, о котором можно было бы говорить. Если вы планируете установить контекстную информацию в хранимой процедуре, а затем полагаться на нее в триггере, который запускается из-за удалений, которые происходят в указанной процедуре, то ваш пакет еще не завершился, поэтому, согласно статье, которую вы связали, вы получаете информация о conetxt из sys.dm_exec_requests DMV или из функции CONTEXT_INFO(). Он еще не будет помещен в sys.dm_exec_sessions, что может произойти только после выхода из хранимой процедуры и завершения любого другого вызова в пакете T-SQL, отправленном на сервер («запрос»).

6 голосов
/ 11 июня 2010

Я использовал этот точный метод для аудита на одном клиентском сайте, и они интенсивно использовали его в течение почти 6 месяцев без проблем.

Контекстная информация распространяется на текущее соединение для текущего пакета и любых пакетов, которые начинаются после завершения текущего пакета. Два пользователя в вашей среде либо не будут подключены к одному соединению, либо, если существует общий доступ к соединению, у них все равно будут свои значения, если они вообще перекрываются. Если один придет за другим, то второй перезапишет первый, но в любом случае это будет сделано к этому времени. По крайней мере, это мое понимание того, как это работает. Вы можете посмотреть MARS (несколько активных наборов результатов) для получения дополнительной информации о нем.

...