Azure SQL数据库上的奇怪池化行为

时间:2018-05-19 18:10:18

标签: sql-server azure azure-sql-database pooling

这个问题是关于Azure SQL数据库上非常奇怪的池行为。

以下是执行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;

我们的Azure SQL Tier限制为600个连接。

我们使用API​​在数据库中生成一些数据。此API在没有共享连接的情况下调用3个不同的SQL命令(sqlCommand.Connection为空,因此closeConnection == true

现在的问题是:在本地SQL Server上,一切正常:我们总是有45-46个连接处于休眠状态,因此池工作正常,没问题,我们可以在数据库中生成数千个项目。

但是在Azure DB中,池的工作方式非常不同。看起来像汇集根本不起作用。 Max Pooling完全被忽略:在对象生成期间很快,连接总数达到了我们层(600)的极限,我们得到了错误:

  

数据库的会话限制为600且已达到。请参阅&#39; http://go.microsoft.com/fwlink/?LinkId=267637&#39;寻求帮助。

并且SQL命令永远不会重用现有连接,它们保持状态为默认.net sql客户端时间(约4分钟)。

即使我的本地Service Fabric连接到Azure DB,我也有同样的行为。

问题:为什么会发生这种情况以及如何避免?

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'

0 个答案:

没有答案