SQL Server事务超时


9

SQL Server 2008 R2中是否有办法导致涉及事务的数据库修改超时?在一种情况下,我们的应用程序代码会挂起或引发异常,并且无法执行回滚或提交。然后,这导致其他会话挂起,等待事务完成。

Answers:


20

扩展Mark的答案...

发生客户端超时事件时(例如.net CommandTimeout),客户端将向SQL Server发送“ ABORT”。然后,SQL Server简单地放弃查询处理。没有事务回滚,没有锁释放。

现在,连接返回到连接池,因此在SQL Server上不会关闭。如果发生这种情况(通过KILL或客户端重新启动等),则将清除事务+锁。请注意,sp_reset_connection不会或不会清除它们,即使已进行了宣传

中止的这种破坏将阻止其他进程。

使SQL Server清除事务+客户端超时锁定(严格来说是ABORT事件)的方法是使用SET XACT_ABORT ON。

您可以验证是否正在SSMS中打开2个查询窗口:

视窗1:

在菜单Query..Query Options中,将超时设置为5秒,然后运行

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

窗口2,这将永远等待(或超时)

SELECT * FROM sometable

SET XACT_ABORT ON也具有有趣的副作用:

  • @@ TRANCOUNT在隐式回滚上设置为零,但是错误266被抑制(如果@@ TRANCOUNT在存储过程的入口和出口不同,则会发生这种情况)
  • XACT_STATE将为-1(“已删除”)

这两者的结合意味着您不能对部分提交/回滚使用SAVEPOINTS(尽管我无法回忆起确切的行为)。哪个适合我

SET XACT_ABORT上的SO链接:

在嵌套的存储过程中:

在sp_reset_connection上:


未来打个招呼!“请注意,即使通过广告宣传sp_reset_connection也不会清除它们,也不会清除它们” –我不认为这在SQL Server的最新版本中是真的吗?
卡米尔克

11

我很犹豫地回答这个问题,因为在您对问题的描述中没有足够的信息可以百分百确定这是最好的建议。“挂断引发异常”表明未正确理解问题的根源,因此请谨慎操作。

最简单的解决方案可能是SET XACT_ABORT ON

XACT_ABORT确定在运行时错误的情况下SQL Server是否将回滚事务。默认值SET XACT_ABORT OFF将仅回滚导致错误的语句,从而使所有父事务保持打开状态。

默认设置的“陷阱”副作用是超时可能导致完全相同的问题,这是客户负责处理和回滚的开放事务。如果客户不尝试/捕获/回滚,则该事务将一直保持打开状态,直到处理(我引用@gbn)的超暴力行为为止KILL <spid>

经常引用Erland Sommarskog关于SQL Server中的错误处理文章,其中包含处理这些情况及更多信息所需的所有背景和策略。

编辑(以下注释):要识别未完成的事务,sp_whoisactive可能是功能最齐全的。


我确实通过某种Google搜索找到了在挂起时查找未结交易的方法-也许这是最好的解决方案。那就是找到导致代码中未完成事务的原因并修复代码中的漏洞。供他人参考。DBCC OPENTRAN返回最早的活动事务-> msdn.microsoft.com/en-us/library/ms182792.aspx还是类似的东西?-> weblogs.sqlteam.com/mladenp/archive/2008/04/29/…–
大卫·格雷·赖特

我一直认为厄兰没有公平对待的SET XACT_ABORT sommarskog.se/error-handling-I.html#XACT_ABORT
GBN
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.