I have 2 queries that get involved in a deadlock situaution displayed in the Deadlockgraph below. (Seitensperre means pagelock)
The query in process 55 is the deadlock victim. It is a select that includes the tables order and payment.
The query on process 95 has a couple of queries in it
At the beginning ist does a couple of selects to store some values into variables (table order is accessed)
It then updates table order and after that table payment.
I dont understand how a deadlock can arise from this situation. Can you explain what the deadlock caused and what I can do about this? I guess I just have hard time reading the deadlock-graph.
Here are the resources involved.
<resource-list>
<objectlock lockPartition="0" objid="1104059019" subresource="FULL" dbid="9" objectname="mycompany.dbo.order" id="lock1b9596980" mode="S" associatedObjectId="1104059019">
<owner-list>
<owner id="process443bac8" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process20fc5eda8" mode="IX" requestType="wait"/>
</waiter-list>
</objectlock>
<pagelock fileid="1" pageid="1825971" dbid="9" objectname="mycompany.dbo.Payment" id="lock1bca33000" mode="IX" associatedObjectId="72057594063159296">
<owner-list>
<owner id="process20fc5eda8" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process443bac8" mode="S" requestType="wait"/>
</waiter-list>
</pagelock>
</resource-list>

EDIT
Here is the Update query (process 95)
ALTER PROCEDURE [dbo].[updateOrderDetails]
(
@id_order int,
@customerComment NText,
@salutationBilling nvarchar(50) = '00',
@companyNameBilling nvarchar(100)= ''
...some more Parameters
)
AS
DECLARE @user_change int, @id_orderAddress int,
@id_voucherType int, @id_orderPayment int, @id_paymentMode int
SET NOCOUNT ON;
SET ANSI_NULLS ON
SELECT @user_change = 0
SELECT @id_orderAddress = 0
SELECT @id_voucherType = 0
SELECT @id_orderPayment = 0
SELECT @id_paymentMode = 0
SELECT @user_change = id FROM user
WHERE logonName = @user_str
SELECT @id_orderAddress = id_orderAddress FROM order
WHERE [id] = @id_order
SELECT @id_voucherType = [id] FROM voucherType
WHERE [name] = @voucherTypeName
SELECT @id_orderPayment = [id_orderPayment] FROM order
WHERE [id] = @id_order
SELECT @id_paymentMode = [id] FROM paymentMode
WHERE [name] = @paymentModeName
IF @user_change = 0 GOTO ERR
IF @id_voucherType = 0 GOTO ERR
UPDATE order
SET
[id_voucherType] = @id_voucherType,
[customerComment] = @customerComment,
[causeOfCancellation] = @causeOfCancellation
...some more fields to update
WHERE
[id] = @id_order
IF @id_orderAddress = 0 GOTO ERR
UPDATE Address
SET
[salutationBilling] = @salutationBilling,
[companyNameBilling] = @companyNameBilling,
[firstNameBilling] = @firstNameBilling
...some more fields to update
WHERE
[id] = @id_orderAddress
IF @id_orderPayment = 0 OR @id_paymentMode = 0 GOTO ERR
UPDATE Payment
SET
[id_paymentMode] = @id_paymentMode,
[customerBankDepositor] = @customerBankDepositor,
[customerBank] = @customerBank,
[customerBankCode] = @customerBankCode,
...some more fields to update
WHERE
[id] = @id_orderPayment
IF @@Error > 0 Goto ERR
RETURN 0
ERR:
return -1;
SET QUOTED_IDENTIFIER ON
Here is the select query (process 55)
ALTER PROCEDURE [dbo].[searchOrders]
(
@SelectType INT
,@searchB2B INT
,@VoucherNumber NVARCHAR(50) = null
,@FirstNameBilling NVARCHAR(100) = null
... some more parameters
)
AS
SET NOCOUNT ON;
IF @SelectType = 0 and LEN(@VoucherNumber) > 0
BEGIN
SELECT DISTINCT (o.id)
,o.voucherNumber
...some more columns
FROM order AS o
LEFT JOIN orderAssignment AS oa ON o.id = oa.id_order
LEFT JOIN voucherType AS vt ON o.id_voucherType = vt.id
LEFT JOIN Payment AS op ON o.id_orderPayment = op.id
LEFT JOIN paymentMode AS pm ON op.id_paymentMode = pm.id
LEFT JOIN orderAddress AS addr ON o.id_orderAddress = addr.id
LEFT JOIN user AS u1 ON o.user_change = u1.id
LEFT JOIN user as u2 ON oa.id_user = u2.id
LEFT JOIN b2bAccount as b2b ON o.id_b2bAccount = b2b.id
WHERE o.voucherNumber like @VoucherNumber
AND o.isB2B = @searchB2B
END
...some more cases depending on @SelectType but the actual query is with @SelectType = 0
RETURN
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
At the end it turned out that it was an issue with the calling code. Its difficult to explain, but basically a transaction was opened and handed over to a couple of methods.
I removed the transaction and the deadlocks went away.
Of course I have to re-implement the transaction again, and see if it is really a problem with how the transaction handling was implemented or if the transaction just spans for too long.