在 MSSQL (TSQL) 中,是否可以指定驻留在连接字符串中但不影响池化的上下文变量

本文关键字:字符串 连接 影响 变量 上下文 TSQL MSSQL 是否 | 更新日期: 2023-09-27 17:55:51

为了进一步解释需求,请考虑以下场景:

在严重依赖TRIGGERS的遗留系统中,我们需要提供某种令牌(我们称之为"SessionID")以插入到某些安全日志表中。此令牌在应用程序服务器中以 C# 创建,并将传递到所有 SQL 命令中。

可悲的是,对触发器的这种要求是不可改变

的因此,

由于我有权修改连接字符串,因此我可以(并且已成功证明我可以)使用"应用程序名称"令牌来提供此信息。

string connectionString = string.Format("SERVER=sql.example.com; "
    + "DATABASE=someDB; User ID=xyz; Password=123; Application Name={0}", sID);

既然这有效,问题出在哪里?

问题很简单...以上有效,但由于我们有成千上万的用户......我们的连接池被销毁(因为连接池是基于连接字符串创建的...基本上,我需要连接池基于Application Name属性之外的所有内容)。

所以,你知道我怎么做吗:

  1. 在连接字符串中设置一个不会包含在池中的属性。
  2. 以其他方式为此连接设置上下文属性,该属性对性能的影响不是很大。

作为旁注...我可以立即打开连接并创建一个具有单个值的临时表:

SELECT 12345 AS SessionID INTO #context

但这似乎非常矫枉过正!

在 MSSQL (TSQL) 中,是否可以指定驻留在连接字符串中但不影响池化的上下文变量

您需要执行此操作而不是依赖连接字符串,而是可以使用临时表SET CONTEXT_INFO/CONTEXT_INFO() 将一些任意数据与当前会话/连接相关联(并且在触发器中可用)。

如果服务器可以接受从用户/时间等的某种组合中创建变量,则可以从登录触发器中自动分配CONTEXT_INFO,在这种情况下,您根本不需要更改连接机制。

我的理解是使用连接字符串作为键创建单独的连接池,因此对连接字符串的任何上下文修改都将不可避免地影响池化

我之前注意到 SqlConnection 类上的 WorkstationId 属性 - 这可能是引入一些上下文化的技术?

            SqlConnection cn = new SqlConnection("CONNECTION_STRING");
            string identifier = cn.WorkstationId;

好的,所以在做了大量的测试之后,我想出了一个解决方案。

  1. 关闭连接池。
  2. 使用"工作站 ID"属性。

在进行了一些基准测试后,我能够看到连接池比不使用池快 50 倍......但。。。不使用池化仍然每个连接只需要 0.005 秒。

我愿意忍受纳秒级的性能损失,以获得我们需要的安全日志记录。

哦,作为旁白 - 如果当前正在使用所有连接,连接池具有主要的性能限制,因为第 101 个排队的人将不得不等待......所以,在某些情况下...连接池比不使用池慢 1,000 倍!

不幸的是,

连接字符串中的所有内容都将用于池化(我认为他们将使用 GetHashCode() 来检查字符串是否已在池中)。