デッドロックを回避し、複数のサービスからの要求を同期するために、私はROWLOCK、READPASTを使用しています。私の質問は、CTE、サブクエリ、およびCTEの更新ステートメントを含むクエリのどこに配置する必要があるかということです。重要な場所は1つありますか、それとも3か所すべてにあるべきですか(下)。または、更新される行のみを選択できるように、このようなクエリを作成するためのより良い方法があるかもしれません。
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