【问题标题】:Sql Transaction doesn't release lock after commitSql Transaction 提交后不释放锁
【发布时间】:2016-01-08 18:03:53
【问题描述】:

我在 SSMS 查询窗口中运行了类似于以下脚本的脚本。脚本成功运行后,受影响的表上仍然存在一些锁。当我尝试关闭窗口时,会显示一个消息框,询问我是否要提交或取消事务。

在我选择其中一个选项后,锁被释放。 什么会导致这种行为?

begin tran
delete from tableA
delete from tableB
insert into tableB
insert into tableA
commit tran 

我已连接到远程 Sql Server 2014 并在本地运行 SSMS 2014

谢谢!

【问题讨论】:

  • 大胆猜测,您在同一窗口中运行了此脚本的早期版本,在 begin tran 之后出错,并且从未到达 commitrollback。第一笔交易仍在进行中。

标签: sql sql-server transactions ssms


【解决方案1】:

以下示例说明了未完成的打开事务如何不释放锁: 打开 SQL Server 查询分析器并运行以下批处理,但在完成之前取消事务:

Begin Tran
Update authors set state = 'CA'
waitfor delay "00:02:00" --Cancel the command
Commit Tran

通过执行以下命令查看持有的锁:

sp_lock

您会看到为 authors 表持有锁。

从同一个服务器进程id(SPID),执行下一批:

Begin Tran
Update titleauthor set au_ord = 0
Commit Tran - Completed transaction.

通过执行以下命令查看持有的锁:

sp_lock

您会看到,尽管最后一个事务已完成,但在 authors 和 titleauthors 表上都持有锁。原因是第一个事务没有完成,当第二个事务从同一个连接执行时,它被视为嵌套事务。

您可以通过发出以下语句检查@@trancount 全局变量来查看事务计数:

select @@trancount

此查询返回 1,表示有一笔交易未完成。

从此连接执行的任何进一步事务都被视为嵌套事务。锁会继续累积,直到执行 ROLLBACK 才会释放,这会回滚到最外面的事务或保存点。 继续该示例,您可以通过从同一连接执行以下事务来了解回滚如何导致已完成的事务被否定:

Begin Tran
Update titles set royalty = 0
Rollback

回滚会将批次回滚到最外层的事务,即使在 titleauthors 上有一个已完成的事务 (2)。已完成事务的回滚发生是因为已完成事务被视为嵌套事务。

为避免此类问题,请在每次事务后检查事务是否完成,使用以下语句:

If @@trancount > 0 rollback

参考:Incomplete transaction may hold large number of locks and cause blocking

【讨论】:

  • 如果您使用其他网站的参考,请根据用户问题和表格更改代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 2011-03-17
相关资源
最近更新 更多