views:

229

answers:

2

Hello everyone,

I am using SQL Server 2008 Enterprise. I am wondering why even a single delete statement of this stored procedure will cause deadlock if executed by multiple threads at the same time?

For the delete statement, 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  

thanks in advance, George

+1  A: 

I don't have experience with concurrency but there are 2 things in your procedure that I would change (and maybe fixing your deadlock):

  • Wrap your whole procedure in a transaction. This is to prevent a scenario like FooProc 1 gets called and is about to execute the SELECT statement while FooProc 2 has just executed the DELETE statement having both the same @Param1.
  • Don't use @@Identity, use SCOPE_IDENTITY instead.

Interesting link about @@Identity vs SCOPE_IDENTITY() vs IDENT_CURRENT()

ZippyV
Thanks ZippyV, any ideas why in my scenraio there is deadlock? Any tools or sample codes which could be used to reproduce deadlock scenario?
George2
http://www.mssqltips.com/tip.asp?tip=1036
ZippyV
Do you think my scenario will cause deadlock if Table FooTable is big?
George2
It depends on Param1. Just implement the 2 changes I suggested and see if you still get deadlock problems.
ZippyV
"It depends on Param1" -- I am interested in this point. Could you explain more about why whether there is deadlock will be dependent on Param1 (its value?)?
George2
It's the amount of rows that have the same Param1 value and how many procedures that are executed at the same time with the same Param1 value.
ZippyV
+1  A: 

The usual answer: it depends! :-)

Mostly on how much traffic you have on your system, and what transaction isolation level you're using.

The isolation level controls how you're getting your data, and how much locking is going on. If you've never heard of transaction isolation levels, you're probably using the default - READ COMMITTED, which shouldn't be too bad a choice.

However, if you'd use something like SERIALIZABLE for any reasons, you might experience not deadlocks - but delays. The table might be locked for a period of time until your one transaction completes. If all operations work in this order (first delete, then insert, then select), I don't see how you should encounter any deadlocks, really.

Read up on SQL Transaction Isolation Levels here on www.sql-server-performance.com.

marc_s
I claimed on @George2's previous deadlock thread that deadlock could ensue between 2 concurrent deletes if they both end up with a parallel execution plan and an allocation of page locks in the "right" order to cause this. However I just tried to get this deadlock to happen in testing and couldn't. I haven't got time to pursue it any further so sorry if I misled you there @George2!
Martin Smith
Hi Mark, any tools or sample codes which could be used to reproduce deadlock scenario?
George2
Hi Martin, any ideas why in my scenraio there is deadlock? Any tools or sample codes which could be used to reproduce deadlock scenario?
George2
Any ideas why in my scenraio there is deadlock? Any tools or sample codes which could be used to reproduce deadlock scenario?
George2
Thanks, question answered!
George2

related questions