SQL Server 事务超时

Dav*_*ght 13 sql-server-2008-r2 transaction locking

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

gbn*_*gbn 24

扩展马克的答案......

当发生客户端超时事件(例如 .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
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM sometable
Run Code Online (Sandbox Code Playgroud)

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

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

这意味着您不能将 SAVEPOINTS(尽管我不记得确切的行为)用于部分提交/回滚。哪个适合我

SET XACT_ABORT 上的 SO 链接:

在嵌套存储过程中:

在 sp_reset_connection 上:


Mar*_*ith 11

我犹豫地回答这个问题,因为您对问题的描述中没有足够的信息来 100% 确定这是最好的建议。“挂起抛出异常”表示未正确理解问题的根源,因此请谨慎行事。

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

XACT_ABORT确定 SQL Server 是否会在出现运行时错误时回滚事务。默认SET XACT_ABORT OFF将只回滚导致错误的语句,保持任何父事务处于打开状态。

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

经常引用的Erland Sommarskog关于SQL Server 中的错误处理文章包含处理这些场景所需的所有背景和策略以及更多内容。

编辑(以下评论):为了识别打开的交易,sp_whoisactive可能是最完整的功能。