我在数据库中有一个过程,它将一些数据插入到同一个数据库的DB_A
表中。Table_A
这是一个非常简单的过程。但是,我发现运行该过程的进程处于 SUSPENDED 或 RUNNING 状态很长时间,超过 30 分钟。
最奇怪的是,这个过程锁定了另一个数据库中的另外两个与该过程完全不相关的表。
流程如下:
use DB_A;
go
create procedure dbo.spAddUrls @sURL nvarchar(500), @dtDate date
as
begin
set nocount on;
declare @nID_ bigint = dbo.ufnGetHash (@sURL);
begin try
begin tran
insert into dbo.TableA (ID, [URL], MapDate)
values (@nID_, @sURL, @dtDate);
commit transaction
end try
begin catch
declare @ErrorMsg varchar(1000) = error_message();
if @@trancount > 0
begin
rollback transaction;
raiserror (@ErrorMsg, 8, 1);
end
end catch
end
但我看到数据库中DB_B
两个不相关的表上有排他锁Table_B
。Table_C
Table_A
inDB_A
没有任何触发器或外键。
为什么表被DB_B
锁了?
注意:所有这些表和过程都是复制的一部分。但我不确定它们是否相关。
除了一些例外情况,锁会一直保持到事务结束。因此该会话所持有的锁可能已被前一个语句获取。
难题的解决方案是,在调用存储过程之前,有带有
Table_B
和 的MERGE 语句Table_C
。最重要的是,在会话开始时就有一条
set implicit_transactions on
声明,它将保持交易开放直到会话结束。感谢大家。