views:

68

answers:

2

Hello everyone,

I am using SQL Server 2008 Enterprise. And using ADO.Net + C# + .Net 3.5 + ASP.Net as client to access database. When I access SQL Server 2008 tables, I always invoke stored procedure from my C# + ADO.Net code.

I have 3 operations on table FooTable. And Multiple connections will execute them at the same time in sequences, i.e. executes delete, the execute insert and then execute select. Each statement (delete/insert/select) is of a separate individual transaction in the single store procedure.

My question is whether it is possible that deadlock will occur on delete statement? My guess is whether it is possible that deadlock occurs if multiple connections are operating on the same Param1 value?

BTW: For the statements below, Param1 is a column of table FooTable, Param1 is a foreign key of another table (refers to another primary key clustered index column of the other table). There is no index on Param1 itself for table FooTable. FooTable has another column which is used as clustered primary key, but not Param1 column.

create PROCEDURE [dbo].[FooProc]    
(  
 @Param1 int 
 ,@Param2 int  
 ,@Param3 int  
)    
AS    

DELETE FooTable WHERE  Param1 = @Param1     

INSERT INTO FooTable    
 (  
 Param1  
 ,Param2  
 ,Param3  
  )    
 VALUES    
 (  
 @Param1  
 ,@Param2  
 ,@Param3  
  )    

DECLARE @ID bigint    
 SET @ID = ISNULL(@@Identity,-1)    
 IF @ID > 0    
 BEGIN    
      SELECT IdentityStr FROM FooTable WHERE ID = @ID 
 END

Here is what the activity monitor table looks like,

ProcessID System Process Login Database Status Opened transaction Command Application Wait Time Wait Type CPU 
52 No   Foo suspended 0 DELETE .Net SqlClient Data Provider 4882 LCK_M_U 0 
53 No George Foo suspended 2 DELETE .Net SqlClient Data Provider 12332 LCK_M_U 0 
54 No George Foo suspended 2 DELETE .Net SqlClient Data Provider 6505 LCK_M_U 0 
(a lot of rows like the row for process ID 54)  

thanks in advance, George

+1  A: 

I do not think you would get a deadlock (this is not my field of expertise), but an explicit transaction would probably be a better choice here. A scenario that comes to mind with this code is the following

Two concurrent calls to the procedure execute with Param1 value of 5, both delete and then both insert, so now you have two records with Param1 value of 5. Depending on your data consistency requirements this might or might not be a concern to you.

An alternative for you might be to actually perform an Update and if no rows are affected (check @@rowcount) then do an Insert all in a transaction of course. Or better yet, take a look at Merge to perform Insert/Update operation in a single statement.

Chris Taylor
Thanks Chris, as far as I know (the guy who met with this issue told me), if executing the same procedure from SSMS, the store procedure executed from SSMS will deadlock on delete statement. But deadlock does not happen on the application (ASP.Net application). Any ideas why? Does the store procedure executed from SSMS has differences (e.g. lower priority than application code?) compared to store procedure executed from application?
George2
@George2, I am no expert in this area and it has been years since I worked on a project that used SQL server, but I can tell you that the code above is not terribly uncommon and I am not aware of any situation where this has dead locked. Are you able to simulate a deadlock in SSMS? If so, you can use SQL Server Profiler to analyse the problem check this link http://msdn.microsoft.com/en-us/library/ms188246.aspx
Chris Taylor
Here is the error message I got from SSMS when executing the same store procedure, any further ideas?Message 1205, Level 13, State 52, the process FooProc, Line 9Services (Process ID 111) and another process is deadlock in the lock | communication buffer resources, and has been chosen as the deadlock victim. Rerun the transaction.
George2
Hi Chris. I also got the activity monitor result when there is deadlock occurs (i.e. when I execute the store procedure in SSMS). Since the SQL Server version I am using is not English version, I manully wrote/convert to an English version of output of activity monitor. Any ideas what is wrong? Here is where to download, http://www.mediafire.com/?vmgqevzvyqt
George2
+1  A: 

I would add an index on Param1 to FooTable; without it, the DELETE is doing full table scan, and that'll create problems with deadlocks.

EDIT

Based on your activity details, it doesn't look like you have deadlocks, you have blocking, many deletes are queueing up while one delete takes place. Again, indexing on Param1 would alleviate this, without it, each delete is going to do a full table scan to find the records to delete, while that is happening, the other delete's have to wait. If you have an index on Param1, it'll process much quicker and you won't see the blocking you are now.

If you have deadlocks, the system will kill one of the involved processes, otherwise nothing would ever process; with blocking, things will process, but very slowly if the table is large.

SqlACID
"and that'll create problems with deadlocks" -- Can you show me a some script to reproduce the deadlock in your described scnario please? The store procedure I posted is the only one store procedure which operates on FooTable.
George2
Here is the error message I got from SSMS when executing the same store procedure, any further ideas?Message 1205, Level 13, State 52, the process FooProc, Line 9Services (Process ID 111) and another process is deadlock in the lock | communication buffer resources, and has been chosen as the deadlock victim. Rerun the transaction.
George2
Hi SqlACID. I also got the activity monitor result when there is deadlock occurs (i.e. when I execute the store procedure in SSMS). Since the SQL Server version I am using is not English version, I manully wrote/convert to an English version of output of activity monitor. Any ideas what is wrong? Here is where to download, http://www.mediafire.com/?vmgqevzvyqt
George2
How big is footable? Do you have more than one processor and what is your setting for parallelism? Are there any triggers on the table? I wasn't able to see the picture; it would be good to run Profiler against the database and add the Deadlock capture.
SqlACID
Hi SqlACID, I posted the activity monitor table into my original reply and you can have a look. Any ideas what is wrong?For your questions, I have 16 processors (a powerful machine), 100k rows for the Footable, and about several thousand concurrent connections from end user on the web. But I am using SQL Server connection pool, so I think the real connection number should not be several thousand, correct?
George2
There is no trigger on the table, and what do you mean "your setting for parallelism"?
George2
Check the configured after running:exec sp_configure 'show_advanced_options',1reconfigureexec sp_configure 'max_degree_of_parallelism'If it is configured as default, optimizer will split the operations up and send to multiple processors; you can override in the proc with a MAXDOP hint which may help.Also see Mark B recommendation for posting deadlock graph
SqlACID
Thanks! Parallelism is prone to deadlock or not in my scenario?
George2
And if I can not reproduce the deadlock, how to post deadlock graph?
George2