I have created a WinForm in Visual Studio which multiple users will access. Whenever a user access the data I want to lock the data so that the other users cannot view the same data at the same time due to some business logic.
Below is my c# code
using (SqlConnection conn = new SqlConnection(connectString))
{
using (SqlCommand cmd=new SqlCommand("get_First_Unscan_Record_withUpdate",conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@usrName", username_Form);
conn.Open();
record_number = cmd.ExecuteScalar().ToString();
}
}
And My SQL Procedure
CREATE PROCEDURE [dbo].[get_First_QC_Record_withUpdate]
@usrName nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare @srno int
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
select top 1 @srno=srno from [KYC].[dbo].[KYC_Index] (XLOCK) where [qc]='N' and [qc_int]='N' and transform_int='Y' and transform_status='Y' order by srno
update KYC_Index set [qc_int]='Y',[qc_int_by]=@usrName,[qc_int_time]=GETDATE(),@srno=KYC_Index.srno where srno = @srno
select @srno
Still my users are getting deadlock error
{"Transaction (Process ID 72) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction."}
What am I doing wrong? Or should I change? Please guide.
update top (1)
withrowlock, holdlock, readpast
, have itoutput
the id, and have an index that covers all fields you are filtering on. – GSergXLOCK
(personally I'd have gone withUPDLOCK
), so it can't be simply a read lock trying to become an update lock. So: do you have a transaction here? there isn't one in your code, but there could be aTransactionScope
in play which could add other locks to your context/SPID.... is there? It kinda feels like you could do all of this in one SQL operation, though ... maybe via anOUTPUT
clause to get thesrno
? The first thing I'd try, though, is usingUPDLOCK
. Then I'd try re-writing as single SQL op. – Marc Gravell