• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Liutauras Vilda
  • Paul Clapham
  • paul wheaton
Sheriffs:
  • Tim Cooke
  • Devaka Cooray
  • Rob Spoor
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:

How can a deadlock occur in a thin client?

 
Ranch Hand
Posts: 109
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,

I have read many threads about deadlock prevention, but I don't understand, how a deadlock can occur. My thin client only calls the book- or the search-method, therefore all the locking code lies on the server:



When a client crashes after locking a record, no deadlock occurs, because unlocking is part of the server. When an exception was thrown during a database-operation, the locked record will be unlocked in any case, because unlock is part of the finally-block, and the unlock-method will call notifyAll() to wake up ALL wait()ing threads.

What's about the following scenario:

  • 1. Client A locks record 1.
  • 2. Client B locks record 2.
  • 3. Client A try to lock record 2 and wait().
  • 4. Client B try to lock record 1 and wait().


  • I can not imagine that this could lead to a deadlock. What will happen in this case? There are 4 threads running on the server. Threads 1 and 2 are currently working on the database. Threads 3 and 4 are wait()ing. When thread 1 (Client A) has finished, it call unlock and notifyAll(). All wait()ing threads are wake up. Thread 3 will check the locked records and wait() again, because record 2 is still locked. Thread 4 will get the lock of record 1 and continue to run. When thread 2 (Client B) has finished, it call unlock and notifyAll(). The only wait()ing thread is thread 3. He will wake up und get the lock of record 2. No deadlock occur.

    I'm not sure whether my assumptions are correct.

    Could someone please comment on my code?

    Regards

    Oliver
     
    Ranch Hand
    Posts: 531
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    A deadlock occurs when a lock is held by a thread which is needed by another thread to proceed, while the first thread needs the lock held by the second thread to proceed.
     
    Ranch Hand
    Posts: 172
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Here's how deadlock was able to occur in my client application, and what I did about it:

    In my application for the B&S problem, I have a reservation system. When the operator clicks "reserve", I lock the record. Then a dialog box appears on the client, asking for the client id that identifies the person making the reservation. (This client id is different upon every reservation, so I must request it.) Whent the operator enters the ID, I perform the update, and unlock the record.

    This solution provides the most assurance. That is, as soon as someone says they want it, it's made inactive so that someone can use it. It worked great. However, there was a design problem: if the "get client id" dialog box is never closed (say the client hung up and the operator went to the toilet) then other users trying to lock that record would be deadlocked. It would stay that way until the original client unlocked the record, or until the client or server were shut down.

    That's no good! So I no longer lock the record until the "get client id" dialog box is closed. This means that you run the risk of getting out-reserved by another operator who is faster at typing, but it means no deadlock.

    From my choices.txt file:


    * Originally when a client wanted to reserve a record, I'd allowed
    the record to be locked before the GUI displayed a dialog box
    requesting the customer id. This meant, however, that if the user
    opened the dialog box and walked away, the record would be locked
    indefinitely, and so would other clients wanting to reserve that
    record. Instead I changed that piece so that the customer Id must
    be input prior to the record being locked.



    The thing that made me decide this funtionality was somewhat acceptable was because the week I finished up my assignment I tried to make a plane reservation and in between starting the reservation and making my payment, someone had taken the last seat on the flight and I lost the ticket during the process.
     
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Robert and Oliver,

    Robert, the scenario you describe supposes a "fat client" design, while Oliver chose the "thin" one (db and business tiers server-side).

    Oliver, indeed, your design avoids any deadlock to occur because of a crashed client.

    As far as your second question is concerned, Anton replied already.

    Regards,

    Phil.
    [ July 26, 2004: Message edited by: Philippe Maquet ]
     
    Oliver Rensen
    Ranch Hand
    Posts: 109
    Eclipse IDE Firefox Browser Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi all,

    thank you for your quick answers!

    Anton: Your deadlock-definition sounds good, but I think my question "I don't understand, how a deadlock can occur" was a little bit misleading. It would be better to ask "I don't understand, whether a deadlock can occur in my design", because there are many discussions and solutions in this forum to prevent deadlocks. Thus, I was not sure whether I must implement explicitly one of these "deadlock preventing solutions".

    Robert: Sorry to hear that you have lost the last ticket from a flight (I suspect this program was a bad implementation from the FBNS-assignment).
    Your dialog-box to insert the client-id is an interesting design-choice. I think about another way to insert the client-id: a text-field in the main-GUI. But I'm not sure whether I should use a text-field or a dialog-box. The dialog-box looks better. But to handle a text-field in the main-GUI is easier to program (I'm a lazy guy, I know). Why do you have choosen the dialog-box rather than a simple text-field?

    Phil: It's good to hear from the Javaranch-deadlock-expert that my design avoid any deadlocks.
    Some months ago you wrote following to prevent deadlocks: "Allowing multiple locks per client, but publish a locking contract (in your Javadoc) that requires from clients that multiple locks are claimed in some specific order (ascending on recNo for instance). And you don't enforces the contract by code (the only thing you do is writing 2 sentences in your Data javadoc)".
    Only to play it safe: Is it correct, that I don't need this contract in my javadoc?

    Regards

    Oliver
     
    Anton Golovin
    Ranch Hand
    Posts: 531
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Oliver Roell:
    Anton: Your deadlock-definition sounds good, but I think my question "I don't understand, how a deadlock can occur" was a little bit misleading. It would be better to ask "I don't understand, whether a deadlock can occur in my design", because there are many discussions and solutions in this forum to prevent deadlocks. Thus, I was not sure whether I must implement explicitly one of these "deadlock preventing solutions".

    a)

    1. Client A locks record 1.
    2. Client B locks record 2.
    3. Client A try to lock record 2 and wait().
    4. Client B try to lock record 1 and wait().

    b)

    try {
    long lockCookie = data.lock(recNo);
    data.update(recNo, data, lockCookie);}
    catch (Exception ex) {
    throw ex;
    }
    finally {
    data.unlock(recNo, lookCookie);
    }




    a)

    This is the perfect deadlock scenario. The reason it is a perfect deadlock scenario is because, having acquired a lock, client tries to ackquire a second lock without releasing the first one. That is the classic definition of possible deadlock. There is not way to tell if step 3 is ever going to complete, and the same about step 4. What if Client A never releases lock on record 1 and Client B never releases lock on record 2? Client A and Client B may wait forever.

    b)

    I think there might be a problem with the code. If you throw an Exception from within the catch block, finally will not to execute because control is transferred elsewhere. Therefore, the record is never unlocked. Finally is not guaranteed to always execute, by the way, especially if there is an exception thrown from catch or there is a return statement in try or catch. (Was I wrong here. )

    [ July 25, 2004: Message edited by: Anton Golovin ]
    [ July 26, 2004: Message edited by: Anton Golovin ]
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Anton,

    If you throw an Exception from within the catch block, finally will not to execute because control is transferred elsewhere. Therefore, the record is never unlocked. Finally is not guaranteed to always execute, by the way, especially if there is an exception thrown from catch or there is a return statement in try or catch.



    This is false. You can run this little test to check it:



    BTW and AFAIK, the only way to avoid a finally block to get executed is calling System.exit().

    Regards,

    Phil.
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Oliver,

    You have basically two scenarios which may lead to a deadlock:

    1) a client crashes while holding (a) lock(s);
    2) crossed lock claims as Anton explained.

    Your thin client approach only prevents scenario 1 to happen.

    Regards,

    Phil.
     
    Anton Golovin
    Ranch Hand
    Posts: 531
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I learn something new everyday. Both rethrown exception and return still have finaaly execute. I wonder what happens after finally executes: does control get transferred as expected?


    [ July 26, 2004: Message edited by: Anton Golovin ]
     
    Oliver Rensen
    Ranch Hand
    Posts: 109
    Eclipse IDE Firefox Browser Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Phil,
    hi Anton,

    thank you for your help.

    I think I'll write the mentioned contract in the javadoc to avoid crossed locks.

    But I'm always not sure what could happen that thread 1 or 2 in the above example are never come back to unlock the records. When the server hangs up or the db-file is corrupt, then it could be, that record 1 or 2 never will unlocked, but in this case the deadlock is secondary, because the complete application would not work, and I must either reboot the server or fix the database. Anyway, with the javadoc-contract I should be safe, isn't it?

    Regards,
    Oliver
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Anton,

    I learn something new everyday.


    Me either...

    Both rethrown exception and return still have finaaly execute.


    The code above doesn't demonstrate the return, but yes.

    I wonder what happens after finally executes: does control get transferred as expected?


    It is.

    Regards,

    Phil.
    [ July 26, 2004: Message edited by: Philippe Maquet ]
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Oliver,

    But I'm always not sure what could happen that thread 1 or 2 in the above example are never come back to unlock the records.



    It's easy for you to check Anton's scenario above: just instantiate two threads (T1 and T2), make T1 grab a lock on recno 1 and then wait 1 second before trying to grab a lock on recno 2, while T2 starts to wait half a second, then grabs a lock on recno 2, waits 1 second, and finally tries to grab a lock on recno 1. Deadlock guaranteed!

    Regards,

    Phil.
     
    Robert Konigsberg
    Ranch Hand
    Posts: 172
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    From Philipe:


    Robert, the scenario you describe supposes a "fat client" design, while Oliver chose the "thin" one (db and business tiers server-side).


    Whoops! Good point.
    From Oliver:


    Your dialog-box to insert the client-id is an interesting design-choice. I think about another way to insert the client-id: a text-field in the main-GUI. But I'm not sure whether I should use a text-field or a dialog-box. The dialog-box looks better. But to handle a text-field in the main-GUI is easier to program (I'm a lazy guy, I know). Why do you have choosen the dialog-box rather than a simple text-field?


    Yeah, that would have been a good way if I knew that no more elements would be to the panel. But what do you do if other dialog box functionality needed to be added later on? Suddenly the screen becomes cluttered with many more graphic elements. Plus, doing dialog boxes is easy once you do one -- the second one is always similar, with similar fields, and that's it, you know?
     
    Oliver Rensen
    Ranch Hand
    Posts: 109
    Eclipse IDE Firefox Browser Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Phil: Thank you for the deadlock-tip. That's the case I have searched for. I will test it, when my Data-class is completed.

    Robert: I know what you mean, and I'll think about it. Thanx for your suggestion.

    Regards,

    Oliver
     
    author
    Posts: 580
    5
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Oliver:

    Actually, your thin client approach to avoiding deadlocks is still perfectly valid, by virtue of the fact that each "update/delete" request will be on separate threads albeit parallel threads. As long as you are consious about the finally block executing, you will be just fine.

    Deadlocks are something that are more of a problem for a thick client because the lock-unlock sequence is not transactional, as seems to be the examples that are being provided...

    Reza
     
    Ranch Hand
    Posts: 357
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Reza,

    Just a question: why do you answer threads that haven't had any traffic for almost a year? Chances that the original posters will read your replies are very slim, I think.

    Frans.
     
    Reza Rahman
    author
    Posts: 580
    5
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Frans:

    I was very excited to see this thread and hoped it would spark renewed interest on the topic (as it did ). Do you know anything that would seem to contradict my assertion? Thanks for sharing your thoughts...

    Reza
     
    Remember to always leap before you look. But always take the time to smell the tiny ads:
    a bit of art, as a gift, that will fit in a stocking
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic