编辑:请参阅 David T Macknet 的答案,这对于 MSSQL 2005 更高版本要好得多。不过,这种技术在其他 DBMS 或更早版本的 SQL Server 上可能仍然有用。
您可以使用第二个表来保存该表是否被锁定的事实。
create table Notifications_Lock(
ix int primary key,
fLocked bit,
constraint Notifications_Lock_SingleRow check (ix = 1)
)
insert Notifications_Lock values( 1, 0, null)
go
create proc NotificationsLockTry
as
begin
update Notifications_Lock set fLocked = 1
from Notifications_Lock with (TABLOCKX)
where fLocked = 0
return @@rowcount
end
go
create proc NotificationsLockTimeout( @waitSeconds int)
as
begin
set @waitSeconds = isnull(@waitSeconds, 0)
declare @dtWaitTill datetime
set @dtWaitTill = dateadd(second, @waitSeconds, getutcdate())
declare @fLocked int
update Notifications_Lock set fLocked = 1
from Notifications_Lock with (TABLOCKX)
where fLocked = 0
set @fLocked = @@rowcount
if @fLocked > 0 return @fLocked
while @fLocked = 0 And @dtWaitTill > getutcdate()
begin
waitfor delay '00:00:01'
update Notifications_Lock set fLocked = 1
from Notifications_Lock with (TABLOCKX)
where fLocked = 0
set @fLocked = @@rowcount
if @fLocked > 0 return @fLocked
end
return @fLocked
end
go
create proc NotificationsUnlock
as
begin
update Notifications_Lock set fLocked = 0, dtLocked = null
from Notifications_Lock with (TABLOCKX)
where fLocked = 1
return @@rowcount
end
示例用法:
declare @fLocked int
-- Wait up to 5 minutes for a lock
exec @fLocked = NotificationsLockTry 300
if @fLocked = 0
begin
raiserror('Unable to lock notifications table', 11,11)
return
end
-- Locked OK
-- INSERT NOTIFICATIONS HERE
-- CALL Send.cmd HERE
exec NotificationsUnlock
return
请注意,如果使用此方法,如果作业退出或中断,您可能必须手动解锁通知表。
您还可以通过将锁定日期添加到表中来添加超时,然后您可以定期检查它,如果它过去太久,只需解锁它。