我们有一个Windows服务,可以协调导入数据库。服务本身不是问题,因为这实际上只是创建一个预定作业,等待它完成然后触发一系列存储过程。问题是其中一个触发器似乎在中途卡住了。这不是一个错误,所以我没有任何东西,我可以作为一个确定的问题。我把它缩小到一个在工作完成后调用的proc。我甚至设法将其缩小到特定的代码行,但这就是我在努力的地方。
proc,将在开始时定义一个事务名称,作为proc的名称和日期时间。它还会从@@TranCount
获取交易计数。然后它定义一个游标,循环与事件关联的文件。在try
块内部,它动态地创建一个视图(这肯定会在我之后写入日志条目时发生)。在此之后,有一个IF
条件,根据持有@@TranCount
的变量是否为零来创建或保存事务。在这种情况下,我会在创建/保存事务之前向我们的日志表写一条消息。
紧接着(无论是创建还是保存)我写了另一条日志消息。日志条目就在那里。我们看到这个暂停的时间,proc总是写入创建事务日志消息。它不会在条件之外写入消息。在第一条消息(pre create / save trans)和第二条消息(post trans)之间发生的唯一事情是创建/保存事务。由于记录的消息是创建消息,因此不能打开事务(@@TranCount
必须为零)。但是,由于没有错误提出,我不能100%确定地说是这种情况。似乎停止的行是CREATE TRANSACTION @TransactionName
行。这似乎意味着某些事情正在锁定并阻止执行该语句。问题是我们可以看到没有打开的事务(DBCC
报告没有打开),proc就在那里挂起。
我们相当肯定它是一些描述的锁定,但完全不知道是什么。为了增加复杂程度,每次都不会发生。有时使用相同的文件,我们可以在此数据库上运行该过程而不会出现任何问题。我们已经尝试在另一个数据库上运行该文件而没有运气复制问题,但我们已经看到它发生在该服务器上的其他数据库上(服务器拥有多个客户端数据库执行相同的操作)。这也只发生在这台服务器上。我们在环境中有其他服务器,看似相同的配置,我们还没有看到这个问题。
遗憾的是,由于内部规则,我们无法发布任何代码,但任何想法都会受到赞赏。
答案 0 :(得分:0)
尝试使用sp_whoisactive并启用锁定标志。我还建议使用下面的代码查找查询计划并分析那里的统计数据。
SELECT * FROM
(
SELECT DB_NAME(p.dbid) AS DBName ,
OBJECT_NAME(p.objectid, p.dbid) AS OBJECT_NAME ,
cp.usecounts ,
p.query_plan ,
q.text ,
p.dbid ,
p.objectid ,
p.number ,
p.encrypted ,
cp.plan_handle
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) p
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS q
WHERE cp.cacheobjtype = 'Compiled Plan'
)a WHERE text LIKE '%SNIPPET OF SQL GOES HERE THAT IS PART OF THE QUERY YOU WANT TO FIND%'
ORDER BY dbid, objectID
答案 1 :(得分:0)
您是否考虑过检查服务的连接属性?如果设置得太低而且proc需要更长时间才能运行,这将导致它断开连接并终止进程。
这比处理交易名称更有可能。