При открытии подключения к SQL Server 2005 из нашего веб-приложения мы иногда видим эту ошибку:
«Олицетворение контекста безопасности сеанса» не может быть вызвано в этом пакете, потому что его вызвал одновременный пакет.
Мы используем MARS и пул соединений.
Исключение происходит из следующего фрагмента кода:
protected SqlConnection Open()
{
SqlConnection connection = new SqlConnection();
connection.ConnectionString = m_ConnectionString;
if (connection != null)
{
try
{
connection.Open();
if (m_ExecuteAsUserName != null)
{
string sql = Format("EXECUTE AS LOGIN = {0};", m_ExecuteAsUserName);
ExecuteCommand(connection, sql);
}
}
catch (Exception exception)
{
connection.Close();
connection = null;
}
}
return connection;
}
Я нашел статью MS Connect , в которой говорится, что ошибка возникает, когда предыдущая команда еще не завершено до отправки команды EXECUTE AS LOGIN. И все же, как это может быть, если соединение только что было открыто?
Может ли это быть как-то связано с пулом соединений, странным образом взаимодействующим с MARS?
ОБНОВЛЕНИЕ: В краткосрочной перспективе мы реализовали обходной путь, очистив пул соединений всякий раз, когда это происходит, чтобы избавиться от плохого соединения, так как в противном случае он продолжает передаваться различным пользователям. (Это теперь происходит 5-10 раз в день с небольшим количеством одновременных пользователей, поэтому это довольно раздражает.) Но если у кого-то есть какие-то дальнейшие идеи, мы все еще ищем реальное решение ...
Я бы сказал, что это MARS, а не объединение
из « Использование нескольких активных наборов результатов (MARS) »
- Приложения могут иметь несколько открытых наборов результатов по умолчанию и могут чередоваться читает от них.
- Приложения могут выполнять другие инструкции (например, INSERT, UPDATE, DELETE и вызовы хранимых процедур), пока открыты наборы результатов по умолчанию .
Пул соединений в его базовой форме означает, что накладные расходы на открытие / закрытие соединения сведены к минимуму, но при любом соединении (до MARS) в любой момент времени происходит что-то одно. Пул существует уже некоторое время и работает из коробки.
MARS (кстати, я не использовал его) вводит перекрывающиеся "вещи", происходящие для любого отдельного соединения. Так что, вероятно, именно MARS, а не пул соединений, является более серьезным виновником 2.
Из « Расширение олицетворения базы данных с помощью EXECUTE AS »
При олицетворении принципала с помощью Оператор EXECUTE AS LOGIN, или в пределах серверного модуля с помощью предложения EXECUTE AS, область действия олицетворения является общесерверной.
Это может объяснить, почему MARS вызывает это: один и тот же принципал в двух сеансах, оба работают с EXECUTE AS. В этой статье использования может быть что-то, или попробуйте следующее:
IF ORIGINAL_LOGIN() = SUSER_SNAME() EXECUTE AS LOGIN = {0};
При размышлении и после прочтения для этого ответа я не уверен, что попытка изменить контекст выполнения для каждого сеанса (MARS) в одном подключении - хорошая идея ...