我有一个通过 SQL 代理作业运行的看门狗进程来管理一些自定义任务。其中一项检查是该进程不再存在:
UPDATE R
SET IsOrphaned = 1, DebugTimestampUtc = GETUTCDATE()
FROM
RequestTable AS R
LEFT JOIN sys.sysprocesses AS P ON
P.spid = R.SPID
WHERE P.spid IS NULL
在 SSMS 中,我运行此语句然后在它完成之前关闭查询窗口(取消查询):
INSERT INTO RequestTable(SPID, CreateTimestampUtc, ...)
SELECT @@SPID, GETUTCDATE(), ...
WAITFOR DELAY '00:00:30.000'
当我手动运行查询以在 SSMS 中标记孤儿时,它在行上匹配,但我的工作没有,因为RequestTable
没有将行标记为孤儿。作业历史记录显示它按计划运行,没有任何错误,运行时间可以忽略不计(< 1 秒)。
此外,当我增加孤儿检测语句时,它还会在我取消查询(并保持查询窗口打开)P.status = 'sleeping'
时立即检测到的记录中找到记录。INSERT ... WAITFOR ...
SQL Server 是否有一些微妙的行为导致sys.sysprocesses
SSMS 和 SQL Agent 之间的表出现这种明显不一致的状态?我也尝试过使用和不使用 NOLOCK 查询提示RequestTable
。
我在 SQL Server 2014 上以 2008R2 的兼容模式运行。
(请注意,使用sys.dm_exec_sessions
instead 仍然表现相同)
谢谢。
PS 这样做的目的是序列化存在并发问题的异步进程。也许还有更好的方法来做到这一点(无法修复异步进程)?
正如Aaron在评论中指出的那样,当前会话已被捕获,因为它们在连接池中被重用。
解决方案是将其过滤掉: