Странное поведение пула в базе данных SQL Azure
Этот вопрос касается очень странного поведения пула в базе данных SQL Azure.
Вот код для выполнения команд SQL:
async Task ExecuteSqlQuery(SqlCommand sqlCommand, Action<SqlDataReader> dataReaderHandler = null)
{
try
{
// share execution between connections
Func<SqlConnection, bool, Task> doQuery = async (connection, closeConnection) =>
{
sqlCommand.Connection = connection;
if (connection.State != ConnectionState.Open)
await connection.OpenAsync();
using (var dataReader = await sqlCommand.ExecuteReaderAsync())
{
dataReaderHandler?.Invoke(dataReader);
}
if (closeConnection)
connection.Close();
};
if (sqlCommand.Connection != null)
{
await doQuery(sqlCommand.Connection, false);
sqlCommand.Dispose();
}
else
{
using (SqlConnection connection = this.connectionSettings.BuildConnection())
{
await doQuery(connection, true);
sqlCommand.Dispose();
}
}
}
catch (Exception er)
{
throw;
}
}
Этот метод работает внутри Azure Service Fabric, которая может работать в двух режимах: локально (работает в Visual Studio и подключена к SQL Server 2016) и в Azure с Azure SQL. Строки подключения в каждом случае:
Data Source=sqlLocal;Initial Catalog=SFDB;Integrated Security=True;MultipleActiveResultSets=False;Connection Timeout=30;
Server=tcp:sqlazure.database.windows.net,1433;Initial Catalog=SFDB;Persist Security Info=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Max Pool Size=200;
Наш уровень SQL Azure ограничен 600 подключениями.
Мы используем API для генерации некоторых данных в базе данных. Этот API вызывает 3 разные команды SQL без совместного использования соединения (sqlCommand.Connection
так нуль closeConnection == true
)
Теперь проблема: на локальном SQL Server все работает нормально: у нас всегда 45-46 подключений в спящем состоянии, поэтому пул работает нормально, нет проблем, мы можем сгенерировать тысячи элементов в базе данных.
Но в Azure DB пулы работают совсем по-другому. Похоже, объединение не работает вообще. Максимальный пул полностью игнорируется: очень скоро при генерации объектов общее количество соединений достигло предела нашего уровня (600), и мы получили ошибку:
Предел сеанса для базы данных составляет 600 и был достигнут. См. " http://go.microsoft.com/fwlink/?LinkId=267637" для получения помощи.
А команды SQL никогда не используют существующие соединения повторно, они остаются в спящем состоянии в течение времени клиента.net sql по умолчанию (~4 минуты).
У меня такое же поведение, даже когда моя локальная Service Fabric подключена к базе данных Azure.
Вопрос: почему это произошло и как этого избежать?
PS: я использую этот запрос, чтобы получить количество соединений (sp_who
показывает тот же счет):
SELECT c.session_id, s.status
FROM sys.dm_exec_connections AS c
JOIN sys.dm_exec_sessions AS s ON c.session_id = s.session_id
WHERE c.session_id <> @@SPID
AND s.status = 'sleeping'