5
爲了避免死鎖和同步來自多個服務的請求,我使用了ROWLOCK,READPAST。我的問題是我應該把它放在一個包含CTE,子查詢和CTE更新聲明的查詢中?是否有一個關鍵點或所有三個地方都有(下方)?或者,也許有更好的方法來編寫這樣的查詢,以便我可以只選擇將要更新的行。在哪裏使用ROWLOCK,帶有CTE,子查詢和更新的READPAST?
alter proc dbo.Notification_DequeueJob
@jobs int = null
as
set nocount on;
set xact_abort on;
declare @now datetime
set @now = getdate();
if(@jobs is null or @jobs <= 0) set @jobs = 1
;with q as (
select
*,
dense_rank() over (order by MinDate, Destination) as dr
from
(
select *,
min(CreatedDt) over (partition by Destination) as MinDate
from dbo.NotificationJob with (rowlock, readpast)
) nj
where (nj.QueuedDt is null or (DATEDIFF(MINUTE, nj.QueuedDt, @now) > 5 and nj.CompletedDt is null))
and (nj.RetryDt is null or nj.RetryDt < @now)
and not exists(
select * from dbo.NotificationJob
where Destination = nj.Destination
and nj.QueuedDt is not null and DATEDIFF(MINUTE, nj.QueuedDt, @now) < 6 and nj.CompletedDt is null)
)
update t
set t.QueuedDt = @now,
t.RetryDt = null
output
inserted.NotificationJobId,
inserted.Categories,
inserted.Source,
inserted.Destination,
inserted.Subject,
inserted.Message
from q as t
where t.dr <= @jobs
go