I have a stored procedure that is running concurrently on schedule and is causing 100's of deadlocks a day. The transaction is managed by the application and the database is using Read-Committed Snapshot Isolation. The SQL that is deadlocking is UPDATE dbo.Job SET IsCalculated = 0 WHERE RfJobStatusID = 2 AND LineID IN (SELECT LineID FROM dbo.Line WHERE PlantID = @nJobPlantID) AND IsCalculated = 1; giving plan [![enter image description here][1]][1] [![enter image description here][2]][2] The deadlock graph is [![enter image description here][3]][3] [1]: https://i.sstatic.net/AJlhi.jpg [2]: https://i.sstatic.net/uOTZt.png [3]: https://i.sstatic.net/us5sw.png Deadlock XML is xml_report <deadlock> <victim-list> <victimProcess id="process1a740339468"/> </victim-list> <process-list> <process id="process1a740339468" taskpriority="5" logused="8180" waitresource="KEY: 6:72057594300858368 (a565e7579a1e)" waittime="3034" ownerId="68453613031" transactionname="user_transaction" lasttranstarted="2022-08-19T12:17:54.910" XDES="0x1a2932bc428" lockMode="X" schedulerid="2" kpid="7176" status="suspended" spid="53" sbid="0" ecid="0" priority="-5" trancount="2" lastbatchstarted="2022-08-19T12:17:54.917" lastbatchcompleted="2022-08-19T12:17:54.913" lastattention="1900-01-01T00:00:00.913" clientapp="Framework Microsoft SqlClient Data Provider" hostname="HSCHT2409" hostpid="1672" loginname="sfol_qasp10" isolationlevel="read committed (2)" xactid="68453613031" currentdb="6" currentdbname="SFOL" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> <executionStack> <frame procname="SFOL.dbo.JobResequence" line="485" stmtstart="56924" stmtend="57904" sqlhandle="0x0300060085ab773fdf91ce00b5ae000001000000000000000000000000000000000000000000000000000000"> unknown </frame> <frame procname="SFOL.dbo.JobReschedule" line="186" stmtstart="27626" stmtend="28404" sqlhandle="0x03000600db843045e4bb37016eae000001000000000000000000000000000000000000000000000000000000"> unknown </frame> </executionStack> <inputbuf> Proc [Database Id = 6 Object Id = 1160807643] </inputbuf> </process> <process id="process1a2e8a38108" taskpriority="5" logused="1147920" waitresource="KEY: 6:72057594300858368 (4d2035f3e54e)" waittime="3041" ownerId="68453402253" transactionname="user_transaction" lasttranstarted="2022-08-19T12:17:48.217" XDES="0x1a10627c428" lockMode="U" schedulerid="3" kpid="4732" status="suspended" spid="58" sbid="0" ecid="0" priority="-5" trancount="2" lastbatchstarted="2022-08-19T12:17:48.220" lastbatchcompleted="2022-08-19T12:17:48.220" lastattention="1900-01-01T00:00:00.220" clientapp="Framework Microsoft SqlClient Data Provider" hostname="HSCHT2409" hostpid="1672" loginname="sfol_qasp10" isolationlevel="read committed (2)" xactid="68453402253" currentdb="6" currentdbname="SFOL" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056"> <executionStack> <frame procname="SFOL.dbo.JobRecalcAllEstimatedDates" line="95" stmtstart="13416" stmtend="13760" sqlhandle="0x03000600a2603c44b5c8c500f6ae000001000000000000000000000000000000000000000000000000000000"> UPDATE dbo.Job SET IsCalculated = 0 WHERE RfJobStatusID = 2 AND LineID IN (SELECT LineID FROM dbo.Line WHERE PlantID = @nJobPlantID) AND IsCalculated = </frame> <frame procname="SFOL.dbo.JobReschedule" line="226" stmtstart="32170" stmtend="32538" sqlhandle="0x03000600db843045e4bb37016eae000001000000000000000000000000000000000000000000000000000000"> unknown </frame> </executionStack> <inputbuf> Proc [Database Id = 6 Object Id = 1160807643] </inputbuf> </process> </process-list> <resource-list> <keylock hobtid="72057594300858368" dbid="6" objectname="SFOL.dbo.Job" indexname="IM_RfJobStatusID_IsCalculated" id="lock1a210631580" mode="U" associatedObjectId="72057594300858368"> <owner-list> <owner id="process1a2e8a38108" mode="U"/> </owner-list> <waiter-list> <waiter id="process1a740339468" mode="X" requestType="wait"/> </waiter-list> </keylock> <keylock hobtid="72057594300858368" dbid="6" objectname="SFOL.dbo.Job" indexname="IM_RfJobStatusID_IsCalculated" id="lock1a23d8c0d80" mode="X" associatedObjectId="72057594300858368"> <owner-list> <owner id="process1a740339468" mode="X"/> </owner-list> <waiter-list> <waiter id="process1a2e8a38108" mode="U" requestType="wait"/> </waiter-list> </keylock> </resource-list> </deadlock> Index is CREATE NONCLUSTERED INDEX IM_RfJobStatusID_IsCalculated ON dbo.Job(RfJobStatusID ASC,IsCalculated ASC) INCLUDE(WOID,EstimatedEndDT,LineID,EstimatedStartDT) And table structure is CREATE TABLE dbo.Job( JobID bigint NOT NULL, WOID bigint NOT NULL, RfJobStatusID tinyint NOT NULL, JobQualityStatusID tinyint NULL, DeadlineDT datetimeoffset(7) NOT NULL, ActualStartDT datetimeoffset(7) NOT NULL, ActualEndDT datetimeoffset(7) NOT NULL, PlannedStartDT datetimeoffset(7) NOT NULL, PlannedEndDT datetimeoffset(7) NOT NULL, PlannedDuration float NOT NULL, EstimatedStartDT datetimeoffset(7) NOT NULL, EstimatedEndDT datetimeoffset(7) NOT NULL, EstimatedDuration float NOT NULL, ScheduledSequence smallint NOT NULL, LineID int NOT NULL, ProductionStartDT datetimeoffset(7) NOT NULL, ProductionEndDT datetimeoffset(7) NOT NULL, TargetCycleTime float NULL, TargetCycleTimeQuantity float NOT NULL, TargetManPower float NULL, TargetSetup float NULL, TargetTearDown float NULL, TargetFixedTime float NULL, QuantityOrdered float NOT NULL, IsCalculated tinyint NOT NULL, LineGroupID int NOT NULL, PassName nvarchar(50) NOT NULL, WorkOrderReleaseStateID int NOT NULL, ProductionCampaignID bigint NULL, CampaignSequence smallint NULL, IsFirstInSequence tinyint NULL, IsLastInSequence tinyint NULL, ProductionSequence smallint NULL, DeadlineLocalDT AS (CONVERT(datetime2,DeadlineDT)) PERSISTED, ActualStartLocalDT AS (CONVERT(datetime2,ActualStartDT)) PERSISTED, ActualEndLocalDT AS (CONVERT(datetime2,ActualEndDT)) PERSISTED, PlannedStartLocalDT AS (CONVERT(datetime2,PlannedStartDT)) PERSISTED, PlannedEndLocalDT AS (CONVERT(datetime2,PlannedEndDT)) PERSISTED, EstimatedStartLocalDT AS (CONVERT(datetime2,EstimatedStartDT)) PERSISTED, EstimatedEndLocalDT AS (CONVERT(datetime2,EstimatedEndDT)) PERSISTED, ProductionStartLocalDT AS (CONVERT(datetime2,ProductionStartDT)) PERSISTED, ProductionEndLocalDT AS (CONVERT(datetime2,ProductionEndDT)) PERSISTED, CONSTRAINT PK_Job PRIMARY KEY CLUSTERED (JobID ASC)) GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_RfJobStatusID DEFAULT ((1)) FOR RfJobStatusID GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_DeadlineDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR DeadlineDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_ActualStartDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR ActualStartDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_ActualEndDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR ActualEndDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_PlannedStartDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR PlannedStartDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_PlannedEndDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR PlannedEndDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_PlannedDuration DEFAULT ((0)) FOR PlannedDuration GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_EstimatedStartDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR EstimatedStartDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_EstimatedEndDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR EstimatedEndDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_EstimatedDuration DEFAULT ((0)) FOR EstimatedDuration GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_ScheduledSequence DEFAULT ((0)) FOR ScheduledSequence GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_LineID DEFAULT ((1)) FOR LineID GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_ProductionStartDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR ProductionStartDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_ProductionEndDT DEFAULT (CONVERT(datetimeoffset,'2050-12-31T00:00:00+00:00',(126))) FOR ProductionEndDT GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_TargetCycleTimeQuantity DEFAULT ((1)) FOR TargetCycleTimeQuantity GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_QuantityOrdered DEFAULT ((0)) FOR QuantityOrdered GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_IsCalculated DEFAULT ((0)) FOR IsCalculated GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_LineGroupID DEFAULT ((1)) FOR LineGroupID GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_PassName DEFAULT ('1') FOR PassName GO ALTER TABLE dbo.Job ADD CONSTRAINT DF_Job_WorkOrderReleaseStateID DEFAULT ((1)) FOR WorkOrderReleaseStateID GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_Line FOREIGN KEY(LineID) REFERENCES dbo.Line (LineID) ON UPDATE CASCADE GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_Line GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_LineGroup FOREIGN KEY(LineGroupID) REFERENCES dbo.LineGroup (LineGroupID) ON UPDATE CASCADE GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_LineGroup GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_ProductionCampaign FOREIGN KEY(ProductionCampaignID) REFERENCES dbo.ProductionCampaign (ProductionCampaignID) `ON UPDATE CASCADE GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_ProductionCampaign GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_RfJobStatus FOREIGN KEY(RfJobStatusID) REFERENCES dbo.RfJobStatus (RfJobStatusID) GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_RfJobStatus GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_WO FOREIGN KEY(WOID) REFERENCES dbo.WO (WOID) GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_WO GO ALTER TABLE dbo.Job WITH CHECK ADD CONSTRAINT FK_Job_WorkOrderReleaseState FOREIGN KEY(WorkOrderReleaseStateID) REFERENCES dbo.WorkOrderReleaseState (WorkOrderReleaseStateID) ON UPDATE CASCADE GO ALTER TABLE dbo.Job CHECK CONSTRAINT FK_Job_WorkOrderReleaseState GO Is anyone able to point me in the right direction or give me some hints on how I maybe able to fix or at least reduce the number of deadlocks?