为了进一步解释这种需要,请考虑以下情况:
在严重依赖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
属性)之外的所有内容。
那么,你知道我怎么做:
作为旁注......我可以立即打开连接并创建一个具有单个值的临时表:
SELECT 12345 AS SessionID INTO #context
但这看起来非常难以理解!
答案 0 :(得分:7)
您需要执行此操作而不是依赖连接字符串,而不是依赖临时表SET CONTEXT_INFO
/ CONTEXT_INFO()
can be used来将某些任意数据与当前会话/连接相关联(并且在触发器中可用)。
如果服务器可以从用户/时间等的某种组合创建变量,则可以在logon trigger内自动分配CONTEXT_INFO
,在这种情况下,您无需更改连接机械师。
答案 1 :(得分:2)
我的理解是使用连接字符串作为键创建单独的连接池,因此对连接字符串的任何上下文修改都将不可避免地影响池化
之前我注意到SqlConnection类上的WorkstationId属性 - 这可能是一种引入一些上下文化的技术?
SqlConnection cn = new SqlConnection("CONNECTION_STRING");
string identifier = cn.WorkstationId;
答案 2 :(得分:1)
好的,经过大量测试后,我想出了一个解决方案。
在进行一些基准测试之后,我能够看到连接池的速度比不使用池的速度快50倍......但是......不使用池化每个连接只需要0.005秒。
我愿意忍受纳秒级性能损失,以获得我们需要的安全日志记录。
哦,作为一个侧点 - 如果目前正在使用所有连接,则连接池具有MAJOR性能限制,因为第101个人必须等待......所以,在 SOME 实例...连接池比不使用池的速度慢1000倍!
答案 3 :(得分:0)
不幸的是,连接字符串中的所有内容都将用于池中(我认为它们将使用GetHashCode()来检查字符串是否已存在于池中。)