Learnings

Friday, February 01, 2008

Causing a simple deadlock

If users A and B both want to update a given row, here is how they can get into a deadlock in an application using cursors:
Assume the code does a SELECT of the row that is to be updated.
1. User A fetches the row first and gets an S lock.
2. User B fetches the same row and gets an S lock too.
3. User A tries to update the row; this will try to get an X lock and wait for B.
4. User B tries to update the row; this will try to get an X lock and wait for A. Deadlock!

Thus, if we declare cursors with just a SELECT and then run multiple copies of the program, it is very easy to deadlock. To avoid this, declare cursors as SELECT FOR UPDATE. In that case,
1. User A fetches the row first and gets a U lock.
2. User B tries to fetch the row and blocks (only one can get a U lock)
3. User A tries to update the row and gets an X lock (remember, even though B is waiting, A's upgrade request will be honoured first since it already holds a lower lock on that object!)
4. User A makes the change and commits, releasing the lock
5. User B now gets the U lock or would have timed out by now.

2 Comments:

  • Nice one.Can you also write some on Lock Escalation? Thanks.

    By Blogger Senthilkumar Bala, at 2:01 AM  

  • Ram,

    But as we know Writers dont wait for Readers, why should an X lock wait for a S lock to be released? Why is that it should have already taken a U lock to achieve this?

    By Blogger Senthilkumar Bala, at 2:11 AM  

Post a Comment

<< Home