Deadlock Scenario is more likely:
Same records in same table
(***_tab) is update with 3 different SP parallel, but the columns are different
(col1,col2,col3).
Table:
CREATE
TABLE ***_tab(
member_id int not null,
state_desc char(2),
business_type varchar(5),
col1 char(1),
col2 char(1),
col3 char(1)
)
go
Index:Create clustered index CL_index_***
on ***_tab (member_id, state_desc)
Go
This 3 SPs are running parllel to update the same records in same table, but different columns.
@ElligibleMember will have some record for processing in batch,
say for example 100
INSERT INTO @ElligibleMember
SELECT top (@batchSize) sm.member_id FROM ***_tab sm WITH (NOLOCK)
WHERE col1 ='N' AND state_desc=@state
SELECT top (@batchSize) sm.member_id FROM ***_tab sm WITH (NOLOCK)
WHERE col1 ='N' AND state_desc=@state
Proc1:
UPDATE
em SET
em.col2='Y'
FROM
***_tab em WITH (HOLDLOCK)INNER JOIN @ElligibleMember ema ON ema.member_id=em.member_id
Proc2:
UPDATE em SET em.col1='Y'
FROM ***_tab em WITH (HOLDLOCK)
INNER JOIN @ElligibleMember emp ON emp.member_id=em.member_id
Proc3:
UPDATE em SET em.col3='Y'
FROM ***_tab em WITH (HOLDLOCK)
INNER JOIN @ElligibleMemberStatus ems ON ems.member_id=em.member_id
Deadlock happens when change to
nonclusterd index
1) P2 (Exclusive)locks the Rowid in Page id = 1743304
2) P1(Update)locks the keylock(Identifies
the key range within an index on which a lock is held or requested) on
HOBT(Represents a heap or b-tree involved in a deadlock) in index “NDX_index_***”
3) P2 is waiting for P1 locked resource
4) P1 is waiting for P2 locked resource
Dead lock happens when change to record
selection using NEWID() and HOLDLOCK,
First
Dead lockprocess6063dc8(P1) = SP1
processe23b708(P2) = SP2
Resource(R1) ridlock fileid=1 pageid=1789383
Owner = P1, waiter = P2
Resource(R2) ridlock fileid=1 pageid=1789411
Owner = P2, waiter = P1
Second Dead Lock
processe26ddc8(P1) = SP1
process12226988(P2) = SP2
Resource(R1) ridlock fileid=1 pageid=1418983
Owner = P1, waiter = P2
Resource(R2) ridlock fileid=1 pageid=1418994
Owner = P2, waiter = P1
1) Covered the Update
statement with a transaction block and Join the Temp table variable in INNER
JOIN which is not recommended but we tested to eliminated the deadlock
2) Tried removing
non-clustered index and created Clustered index , added WITH(HOLDLOCK) in
update statement.
3) And give NEWID(), in
the select statement to picks the random record from selecting the different rows in
other SP, so that 3 sp can update random records.
4) Eliminate join in Update, because the Temp
table Variable records are not deleted, so planned to use Update (@batchSize)
as select Statement
5) Place the With(UPDLOCK) in Select so that it
can prevent the records being read by other SPs
6) Planned to Catch the deadlock in try..catch
block and redo the process(Update statement), which is not recommended in
medisys, we are trying to eliminate the deadlock.
7)Change the logical flow of 3 SP by sequential
Solution in our scenario got by 7th option
7)Change the logical flow of 3 SP to sequential