我在SSMS查询窗口中运行了类似下面的脚本。脚本成功运行后,某些锁定仍保留在受影响的表上。当我尝试关闭窗口时,会显示一个消息框,询问我是否要提交或取消交易。
在我选择其中一个选项后,锁被释放。 什么可能导致这种行为?
begin tran
delete from tableA
delete from tableB
insert into tableB
insert into tableA
commit tran
我已连接到远程Sql Server 2014并运行localy SSMS 2014
谢谢!
答案 0 :(得分:4)
以下示例说明了未完成的打开事务如何不释放锁: 打开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
您会看到尽管最后一个事务已完成,但作者和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