views:

330

answers:

2

I'm writing an application in C# which accesses a SQL Server 2005 database. The application is quite database intensive, and even if I try to optimize all access, set up proper indexes and so on I expect that I will get deadlocks sooner or later. I know why database deadlocks occur, but I doubt I'll be able to release the software without deadlocks occuring at some time. The application is using Entity Framework for database access.

Are there any good pattern for handling SQLExceptions (deadlocked) in the C# client code - for example to re-run the statement batch after x milliseconds?

To clarify; I'm not looking for a method on how to avoid deadlocks in the first place (isolation levels, indexes, order of statements etc) but rather how to handle them when they actually occur.

+1  A: 

Here is the approach we took in the last application framework I worked on. When we detected a deadlock, we simply reran the transaction. We did this up to 5 times. If after 5 times it failed, we would throw an exception. I don't recall a time that the second attempt ever failed. We would know because we were logging all activity in the backend code. So we knew any time a deadlock occurred, and we knew if it failed more than 5 times. This approach worked well for us.

Randy

Randy Minder
Can you tell me how you did the actual rerunning of the transaction? Did you place a simple for-loop around the code in every place where you had a transaction or did you come up with a more generic solution?
martin
We implemented a loop. If the transaction failed, because of a deadlock situation, we rolled the entire transaction back, and tried again up to 5 times.
Randy Minder
A: 

I posted a code sample to handle exactly this a while back, but SO seemed to lose my account in the interim so I can't find it now I'm afraid and don't have the code I used here.

Short answer - wrap the thing in a try..catch. If you catch an error which looks like a deadlock, sleep for a short random time and increment a retry the counter. If you get another error or the retry counter clears your threshold, throw the error back up to the calling routine.

(And if you can, try to bung this in a general routine and run most/all of your DB access through it so you're handling deadlocks program-wide.)

EDIT: Ah, teach me not to use Google! The previous code sample I and others gave is at http://stackoverflow.com/questions/320636/how-to-get-efficient-sql-server-deadlock-handling-in-c-with-ado

eftpotrm