I have 2 jobs scheduled at the same time 9am both calling using a loop container which downloads a SSRS report per iteration, but the job reported a deadlock on a stored procedure used in the process that gets the ID of the next report off the rank to run and it tags the row that it is in use by updating a status column.
The stored procedure:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
DECLARE @ReportID INT
SELECT TOP 1 @ReportID = SSRSReportId
FROM dbo.ReportAutomationThreadQueue WITH (UPDLOCK)
WHERE ReportRunName = @ReportRunName
AND ExtractStatus IS NULL
UPDATE dbo.ReportAutomationThreadQueue
SET ExtractStatus = 'Pending',
ThreadInstanceNumber = @ThreadInstanceNumber
WHERE ReportRunName = @ReportRunName
AND SSRSReportId = @ReportID
COMMIT TRAN
After the transaction it just returns the rows including report parameter information or nothing if nothing more left in the queue:
SELECT
SSRSReportId,
RelativePath,
FileName,
ParameterId,
ParameterName,
ParameterValue
FROM dbo.ReportAutomationThreadQueue
WHERE ReportRunName = @ReportRunName And SSRSReportId = @ReportID
As I see it this should never deadlock as the second call must wait on the SELECT statement before proceeding until the first process finishes its update.
2 jobs will have different @ReportRunName values. Do I need a RowLock or a Holdlock perhaps?
How do I simulate as running 2 jobs at the same time I could try a million times, and it will not clash. Maybe I could try a delay perhaps to guarantee a lock. I am trying to figure out if the deadlock occurred in the same job or separate jobs.
The job itself for a single ReportRunName that can download at most 10 reports does not take that long a couple of minutes or less to run as it is calling config and reports from a DWH so not operational so, you might say just reschedule the second job to be a 5 minutes later. But I am still curious to know what or how to fix.
The only other thing to add of the 2 jobs that were scheduled to run at the same time, one of them finished successfully in 1:04 mins and the second job chosen as the deadlock victim stopped after 12 secs. Does this mean it took 12 seconds of initialisation in the job before it called the stored procedure for the first time or perhaps the first report only took 12 seconds to download, and the deadlock might have occurred on the second time around the loop. I cannot believe the same job would cause a deadlock so it must be the fact 2 jobs are running at the same time. I am dismissing any third possibility of some other process running I am not aware of causing it.
UPDATE TOP 1 ... OUTPUT inserted.SSRSReportId ... This will both update a single row and return its ID