File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Questions regarding locking Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Questions regarding locking" Watch "Questions regarding locking" New topic
Author

Questions regarding locking

Rodrigo Uchoa
Greenhorn

Joined: Feb 12, 2008
Posts: 16
Hey everyone,

I've read quite a bit of posts about locking, but none of them seem to address the same issue I'm thinking right now. Which is why I think I'm missing something related to this whole locking thing.

According to the instructions, if a thread (client) tries to lock an already locked record, it should wait (use of wait() method) until that record is unlocked (possibly forever until notifyAll(), no timeout) so it can proceed. But doesn't this mean the last thread will always overwrite the first one's update? When the better solution, would be to display a message to the last thread so it could try again?

Let's picture two users, John and Bill. They both want to book record number 6, and they highlight and hit the "book" button at almost the same time. If Bill was a bit faster, he would book the record successfully with his ID, while John's GUI would be waiting Bill's lock to end. But as soon as Bill was done, John would proceed his booking without ever realizing someone had booked that record already. And so, Bill's booking would be overwritten.

Is this really what the instructions want us to do?


http://rodrigouchoa.wordpress.com

OCPJP, OCMJD, OCPJWCD, OCPJBCD , OCMJEA, RHCJA.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4490
    
    8

No. What needs to happen is that once John's request gets hold of the lock it should check to see of the record is already booked. And if so, it should bail out.

That's why the locking is needed. Otherwise, John's thread could check if the record was booked, decide is wasn't, but then Bill could book the record before John completes. Then you would get overwriting.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2268
    
    3

Fala Rodrigo! Tudo tranquilo?

So, the key is what my good buddy Matthew said above. Before updating a record, you have to verify if it wasn't booked to another customer. When you get the record's lock, you also have to verify if it still exists, because, since using the delete method also demands the usage of the locking mechanism, it may have been deleted when you aquire its lock. And no, you don't have to implement a delete feature in your assingment. But, if it has to be implemented in the future, your book() method is already prepared.


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Rodrigo Uchoa
Greenhorn

Joined: Feb 12, 2008
Posts: 16
Ok guys,

I'm starting to make sense out of this. One more thing though: While the lockRecord method's signature throws a RecordNotFoundException, it doest not throw any other exception indicating that the record is already booked.

What I can picture in my mind, is that the code to validate if the record is already booked will be in the service layer, while the validation for a deleted record will be inside the "Data" class itself. Something like:




Did I get this right? Doesn't look pretty.

Thanks!

John Oconnor
Ranch Hand

Joined: Jan 12, 2011
Posts: 66

Rodrigo Uchoa wrote:






Why firts try lock a registry, and later ask if already is booked?, this fail because you are throw a alreadyBookedException, so the unlock never is executed.

Use a try/finally block ( so always finaly block execute the unlock method) or first ask if the record are booked, and later try lock and avoid a lock/unlock over bookeds records!

regards!


SCJP 5 - OCMJD 6 - OCPJME1MAD(SCMAD)
Rodrigo Uchoa
Greenhorn

Joined: Feb 12, 2008
Posts: 16
Why firts try lock a registry, and later ask if already is booked?, this fail because you are throw a alreadyBookedException, so the unlock never is executed.

Use a try/finally block ( so always finaly block execute the unlock method) or first ask if the record are booked, and later try lock and avoid a lock/unlock over bookeds records!


What about this scenario?



If the two requests happen at almost the same time, they'll both get TRUE. One of them, the latter, will be waiting for the lock and then will overwrite the first one's update, since there's no checking inside the lock or update for an already locked record. So there should be some kind of locking before the thread asks for the availability of a record. Am I wrong?
John Oconnor
Ranch Hand

Joined: Jan 12, 2011
Posts: 66

Rodrigo Uchoa wrote:

If the two requests happen at almost the same time, they'll both get TRUE. One of them, the latter, will be waiting for the lock and then will overwrite the first one's update, since there's no checking inside the lock or update for an already locked record. So there should be some kind of locking before the thread asks for the availability of a record. Am I wrong?



ohhhohhhh this is another problem....... I have mark a error in your first solution, because when throw a exception the unlock NEVER IS EXECUTED!!! the record are locked forever....


Now you can try use a syncronized block, come think how!.
Already you have almost all method in your bussines class defined....

I have think too much in latest months. good luck!

REgards
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5599
    
  15

John Oconnor wrote:Why firts try lock a registry, and later ask if already is booked?, this fail because you are throw a alreadyBookedException, so the unlock never is executed.

You have to check if the record is already booked by another customer, so Rodrigo is correct: you have to check if the record is already booked. I don't think you would like it if you show up at a hotel with the love of your life for a very romantic weekend (including a wedding proposal), and the room you booked, is already taken by another couple That's why you have to check if the room is already booked
But you are also correct: you ALWAYS must unlock a record, even if you throw an AlreadyBookedException, so the unlock-call should always happen in a finally-block!

John Oconnor wrote:or first ask if the record are booked, and later try lock and avoid a lock/unlock over bookeds records!

That makes no sense at all! Imagine the following scenario: I check the availability of the record and I'm lucky: it is available. Then another client (thread) swoops in, locks the same record, updates the customer id and unlocks this record. Then it's back my turn and my thread locks the record, updates the record and unlocks the record. This results again in a double booked room, something you definitely want to avoid! So you first have to lock the record prior to checking if it's still available. If you successfulle have locked the record, you are guaranteed that no other thread will update this record.

The solution for this problem is like Rodrigo suggested with his initial thought, only he has to add the code in a try/finally block:

Just a note: when the lock-method throws a RNFE, unlocking the record is not necessary because it was never locked, so maybe some small changes need to be made to the above code if your unlock-method throws an exception if you try to unlock a record which is not locked...

Good luck, guys!


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Rodrigo Uchoa
Greenhorn

Joined: Feb 12, 2008
Posts: 16
John was right about that finally block. I completely forgot about it.

What I don't like about my initial solution, is the fact that there are "business validations" happening in two different places. The service layer, or the data layer, should do both checks if the record is already booked and if it still exists (not deleted). Doing one check in one layer, and one check in another, just seems not right. But.. it works
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5599
    
  15

Rodrigo Uchoa wrote:What I don't like about my initial solution, is the fact that there are "business validations" happening in two different places. The service layer, or the data layer, should do both checks if the record is already booked and if it still exists (not deleted).

Totally don't agree! Checking if a record is still available is a business validation, so should happen in some business layer. Your data layer is only concerned about the data, so adding a business validation in your data class is completely wrong and makes your data class completely not reusable! The data class is only interested in the integrity of the data and your database file, so checking if the size of a record field is not too long, is something that should happen in your Data class. Checking if the room already exists or if the customer id is an 8-digit number is something which should happen in a business layer. When you seperate these validations you can reuse your Data class to process a similar database file containing hotels, customers,... If you add specific room validations, you can't anymore.

Don't forget: OO is all about code reusability! (and of course some other things too )
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Questions regarding locking