Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should you request timeouts on locks in .NET?

In Release It!, Michael Nygard reasons that many catastrophic system failures are often caused by a chain of things going wrong. For example, two threads deadlock. There's now two less threads in the thread pool, so load increases on the other threads increasing their likelihood of deadlocks. Suddenly, the server does not respond at all, because the thread pool is exhausted, which causes the load balancer to divert traffic to the other servers (who are all running the same code), which increases their likelihood of deadlocks. Suddenly the whole farm is offline.

Most RDBMS servers detect deadlocks and decide a "loser" (one transaction is aborted, the other can continue). By contrast, in C#, the lock statement will wait indefinitely for a lock to be acquired.

You can however call Monitor.TryEnter(lockObject, TimeSpan) to request a lock or timeout. It returns false if the timeout expires and the lock could not be acquired. Some have wrapped this in using statements to keep a nice syntax.

So my question is, do you always acquire locks using timeouts, or not? And what issues do timeouts create versus a deadlock scenario?

like image 261
Paul Stovell Avatar asked Jan 30 '09 19:01

Paul Stovell


2 Answers

I normally do use timeouts. The biggest issue here is that if the timeout is reached, the requesting operation is going to be aborted. This is obviously preferrable to deadlocking. There's a bigger problem there though: if the operation is critical and you start aborting because something else is deadlocked, if your design is not sound, you could end up causing the farm-going-down issue you described via this method (though softer: your app will no longer work, but you haven't lost control).

The main difference is that you actually have control here, whereas if threads start deadlocking, there's nothing you can do within your code to fix the problem once the failure has started.

like image 95
TheSmurf Avatar answered Oct 17 '22 03:10

TheSmurf


As a general rule I never create locks with infinite timeouts. It simply leads to hard-to-find and hard-to-debug deadlocking. It doesn't take any added work to add a timeout check, even if it just throws an exception, and it notifies you almost immediately if you have a deadlock. More importantly it helps you find bottlenecks caused bu locks that may not cause full deadlocks.

like image 26
ctacke Avatar answered Oct 17 '22 04:10

ctacke