Here is a typical UPDATE T-SQL we are having deadlock issues with. Just two users attempting to save data that is not related to each other, causes a deadlock. I suspect some things but I am not a DBA and know enough SQL as a programmer to get me by. Any help would be appreciated, I have done a lot of reading on deadlock issues but am still unsure.
The deadlock is a KEY type for a TRANSACTION that is X- exclusive.
WHERE WULaborHoursId = @WULaborHoursId
AND LastChanged = @LastChanged;
WULaborHoursId is the primary key but LastChanged is not part of any index. Would this cause a table scan? Can a Timestamp that changes be part of the primary key? This does not sound like a good idea. Would creating an index on the LastChanged Timestamp eliminate a table scan?
SELECT @LastChanged = LastChanged
FROM dbo.WorkUnitLaborHours
WHERE WULaborHoursId = @WULaborHoursId
This SELECT right after the UPDATE is something new to me that was introduced by my new boss and is part of some Framework they used in previous developments. I am not used to performing a SELECT right after an UPDATE and it seems it would share the transaction scope of the UPDATE which may not be desirable?
Here is the UPDATE stored proc:
ALTER PROCEDURE [dbo].[UpdateWorkUnitLaborHours] @WULaborHoursId UNIQUEIDENTIFIER, @WULaborResId UNIQUEIDENTIFIER, @LaborHours DECIMAL(12,2), @StartDate SMALLDATETIME, @EndDate SMALLDATETIME, @DistCurve VARCHAR(20), @UserId UNIQUEIDENTIFIER, @LastChanged Timestamp OUT AS /******************************************** Purpose: Update a Work Unit Labor record for a particular Work Unit Maintenance Logs: Developer Date Description --------- -------- ----------- bbalok 09/19/08 Created *********************************************/ UPDATE WorkUnitLaborHours set LaborHours = @LaborHours, StartDate = @StartDate, EndDate = @EndDate, DistCurve = @DistCurve, LastUpdatedBy = @UserId, LastUpdatedDate=GetDate() WHERE WULaborHoursId = @WULaborHoursId AND LastChanged = @LastChanged; IF @@ROWCOUNT = 0 --handling of concurrency issue based on @lastChanged RAISERROR('Row has been edited by another user', 16, 1) SELECT @LastChanged = LastChanged FROM dbo.WorkUnitLaborHours WHERE WULaborHoursId = @WULaborHoursId