I'm experiencing a deadlock on an old version of one of our software, on a single request of the same stored procedure that was ran pretty much at the same time by two different users.
Request 1 :
UPDATE [UserExport].[Stat] WITH (ROWLOCK)
SET BOKey = CustomerID + '|' + ISNULL(Period, '') + '|' + ISNULL(FECode, '')
WHERE CompanyCode = '001' AND BOKey IS NULL AND UserCode = '53'
Request 2 :
UPDATE [UserExport].[Stat] WITH (ROWLOCK)
SET BOKey = CustomerID + '|' + ISNULL(Period, '') + '|' + ISNULL(FECode, '')
WHERE CompanyCode = '001' AND BOKey IS NULL AND UserCode = '87'
SQL Profiler output (ridlock part only)
<ridlock fileid="3" pageid="55475" dbid="7" objectname="PRTE.UserExport.Stat" id="lock1b722b980" mode="X" associatedObjectId="72057594355384320">
<owner-list>
<owner id="process4a9708" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process55d4c8" mode="U" requestType="wait"/>
</waiter-list>
</ridlock>
<ridlock fileid="3" pageid="155604" dbid="7" objectname="PRTE.UserExport.Stat" id="lock1b7999580" mode="X" associatedObjectId="72057594355384320">
<owner-list>
<owner id="process55d4c8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process4a9708" mode="U" requestType="wait"/>
</waiter-list>
</ridlock>
We are running this on SQL Server 2008 R2, the UserExport scheme is used as a mirror of the dbo one to store data to be exported, and none of its tables have indexes nor triggers. I know the design is bad, actually it was rewritten in future versions as it should be, however I still don't understand how the deadlock can occurs on a RID since there is no way both requests were updating the same line.
I have read here that an UPDATE statement with ROWLOCK hint may lock more rows than it actually updates when running on a table with no index because it also lock other read rows, but I can't find any further explanation or way to deal with it by only updating the request.
Does it mean that an UPDATE on a table with no index is always that risky ?
Or maybe I misunderstand something and there is a way to guarantee only updated rows are locked ?