我同意应该从根本上解决问题,因此 C# 代码必须正确处理它们,但以防您冒着降低活动生产服务器的风险,就像我的情况一样。
我发现我可以使用 SQL 脚本来关闭空闲 200 多分钟以来的所有连接,而对设计不良的软件基本上没有影响/问题。
我没有从程序中调用它,而是将下面的代码放在 SQL Server 代理作业的 STEP 中,因此它会定期从 SQL 服务器本身运行。
就我而言,我想确保不删除某些连接,即来自精心设计的软件或来自 SQL Server 代理本身的连接。所有这些“NEVER TOUCH”连接都由之后的 where 条件标识
DELETE FROM #Who2
最终,一旦通过在该删除中使用 ProgramName NOT IN ('YOURAPPNAME') 在连接字符串上正确设置了 applicationName,您就可以轻松地排除除来自 C# 应用程序的连接之外的所有连接
DECLARE @Now DATETIME
DECLARE @Cmd nvarchar(200)
DECLARE @SpId int
DECLARE @logn nvarchar(30)
DECLARE @pgm nvarchar(max)
SET @Now = GetDate()
CREATE TABLE #Who2(
[SPID] int,
[Status] SysName NULL,
[Login] SysName NULL,
[HostName] SysName NULL,
[BlkBy] SysName NULL,
[DBName] SysName NULL,
[Command] SysName NULL,
[CPUTime] int NULL,
[DiskIO] int NULL,
[LastBatch] SysName NULL,
[ProgramName] SysName NULL,
[SPID2] int NULL,
[RequestId] int NULL)
INSERT #Who2 exec sp_Who2
DELETE FROM #Who2
WHERE Login IN ( 'sa' , 'visora' )
OR HostName='.'
OR ProgramName IN ('Java_Orbiter' , 'Tomcat7_Jsipert2')
OR DBName in ('msdb')
ALTER TABLE #Who2
ADD LastDate DateTime
IF Month(@Now)=1 And Day(@Now)=1
BEGIN
UPDATE #Who2
SET LastDate=
CASE WHEN LastBatch Like '12%'
THEN Cast( Substring(LastBatch,1,5)+ '/'+
Cast(Year(@now)-1 As varchar(4)) +' '+
Substring(LastBatch,7,8) as DateTime)
ELSE
Cast( Substring(LastBatch,1,5)+ '/'+
Cast(Year(@now) As varchar(4))+' ' +
Substring(LastBatch,7,8) as DateTime)
END
END
ELSE
BEGIN
UPDATE #Who2
SET LastDate=Cast( Substring(LastBatch,1,5)+ '/'+
Cast(Year(@now) As varchar(4))+' ' +
Substring(LastBatch,7,8) as DateTime)
END
DECLARE Hit_List CURSOR FOR
SELECT SPID, login, ProgramName FROM #Who2 Where Abs(DateDiff(mi,LastDate,@Now)) > 200
OPEN Hit_List
FETCH NEXT FROM Hit_List into @SpId, @logn, @pgm
WHILE @@FETCH_STATUS=0
BEGIN
SET @Cmd='KILL '+Cast(@SpId as nvarchar(11))+' /* '+@logn +' / ''' + @pgm + ''' */ '
EXEC(@Cmd)
PRINT @Cmd
FETCH NEXT FROM Hit_List into @SpId, @logn, @pgm
END
CLOSE Hit_List
DEALLOCATE Hit_List
DROP TABLE #Who2
GO