Tom*_*m V 7 sql-server connection-pooling microsoft-dynamics
我正在使用 3 层应用程序 Microsoft Dynamics AX,其中中间层维护与 SQL Server 的连接。几个客户端连接到这个中间层服务器。
中间层服务器通常有几个连接到 SQL Server,所以我很确定它们正在池中,但是没有关于如何实现的文档。
通常情况下,我们可以不涉及SPID的用户或客户端应用程序,但在这里我们可以设置一个注册表项(具体到Microsoft Dynamics AX),这使得在提供这些信息的选择context_info的领域sys.dm_exec_sessions。
同样,没有关于如何实现的文档。我们在这方面的唯一信息是MSDN 上一个模糊的博客条目。
帖子提到
添加此信息的性能开销很小。
因此,我们不知道任何实现细节,例如:
有什么方法可以确定服务器端连接池的工作方式以及 context_info 的影响是什么?
更新:
从这里使用这个查询
SELECT des.program_name,
des.login_name,
des.host_name,
-- der.database_id,
COUNT(des.session_id) AS [Connections]
FROM sys.dm_exec_sessions des
INNER JOIN sys.dm_exec_connections DEC
ON des.session_id = DEC.session_id
WHERE des.is_user_process = 1
--AND des.status <> 'running'
GROUP BY des.program_name,
des.login_name,
des.host_name
-- ,der.database_id
HAVING COUNT(des.session_id) > 2
ORDER BY COUNT(des.session_id) DESC
Run Code Online (Sandbox Code Playgroud)
我可以看到使用了连接池。
首先,CONTEXT_INFO是会话的属性,而不是连接。当同一个会话被重用并执行第一批时,它会被sp_reset_connection重置。似乎在 SQL Server 2000 和可能更早的版本CONTEXT_INFO中没有重置,但从 SQL Server 2005 开始它肯定被重置为NULL.
这里的部分混淆是该问题特定于“Microsoft Dynamics AX”,因为一般的 .NET 编程不会具有该博客文章中提到的注册表项。此外,Microsoft Dynamics 随后存储的信息CONTEXT_INFO是其应用程序会话详细信息,这与 SQL Server SPID 无关,不能用于推断连接池正在发生,因为应用程序会话自然会跨越多个连接以及 SPID .
用于设置的机制CONTEXT_INFO必须是在该会话的任何其他查询之前执行的单独的附加查询。类似的东西:
SqlConnection _Connection = new SqlConnection("{connection-string}");
_Connection.Open();
if(_IsConnectionContextRegistryKeySet)
{
SqlCommand _Command = _Connection.CreateCommand();
_Command.CommandType = CommandType.Text;
_Command.CommandText = @"DECLARE @BinaryInfo VARBINARY(128);
SET @BinaryInfo = CONVERT(VARBINARY(128), @StringInfo);
SET CONTEXT_INFO @BinaryInfo;";
SqlParameter _ParamInfo = new SqlParameter("@StringInfo", SqlDbType.VarChar, 100);
_ParamInfo.Value = String.Format("{0} {1} {2}...", AXuserID, AXsessionID, ...);
_Command.Parameters.Add(_ParamInfo);
_Command.ExecuteNonQuery();
_Command.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
因此,为设置此信息而产生的少量额外开销来自此额外查询的执行。
其次,您可以使用 SQL Server Profiler 测试连接池。在“Stored Procedures”类别中选择“RPC:Completed”事件,确保为该事件检查“TextData”、“ClientProcessID”和“SPID”(至少,如果您愿意,可以选择其他列)。然后,转到“列过滤器”,选择“TextData”,并在“Like”条件中添加以下条件:exec sp[_]reset[_]connection. 现在运行该跟踪。如果您看到exec sp_reset_connection 的实例通过,则这是由于使用了连接池。
此外,连接池的两个副作用可能会或可能不会出现在 DMV 中,具体取决于请求的连接数量。下面的查询应该捕获许多/大部分被池化的连接(请注意,它与 CONTEXT_INFO 无关):
SqlConnection _Connection = new SqlConnection("{connection-string}");
_Connection.Open();
if(_IsConnectionContextRegistryKeySet)
{
SqlCommand _Command = _Connection.CreateCommand();
_Command.CommandType = CommandType.Text;
_Command.CommandText = @"DECLARE @BinaryInfo VARBINARY(128);
SET @BinaryInfo = CONVERT(VARBINARY(128), @StringInfo);
SET CONTEXT_INFO @BinaryInfo;";
SqlParameter _ParamInfo = new SqlParameter("@StringInfo", SqlDbType.VarChar, 100);
_ParamInfo.Value = String.Format("{0} {1} {2}...", AXuserID, AXsessionID, ...);
_Command.Parameters.Add(_ParamInfo);
_Command.ExecuteNonQuery();
_Command.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
此查询查找正在使用的连接池的以下指示:
SqlCommands。沿着类似的线,它也应该通过创建一个临时表,并且每隔几秒钟,捕获两个是可能的测试连接池[session_id](INT)和[connection_id]从(UNIQUEIDENTIFIER) sys.dm_exec_connections。然后,只需查找具有相同 connection_id 但不同 session_id 的行。
最后,问题中发布的查询对于指示大多数 Web 应用程序的连接池无效。这里的问题是,通常情况下,“program_name”、“login_name”和“host_name”的属性对于 web/app 服务器建立的所有连接都是相同的(因此需要每个处理器/每个核心的许可模型而不仅仅是拥有 CAL 模型)。
| 归档时间: |
|
| 查看次数: |
1696 次 |
| 最近记录: |