This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes B&S: unlock() method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "B&S: unlock() method" Watch "B&S: unlock() method" New topic
Author

B&S: unlock() method

hatim osman
Ranch Hand

Joined: Jun 10, 2005
Posts: 105
Hi there,

When we lock a record, a RecordNotFoundException is thrown if the record doesn't exists. Logically, the unlock() method should never throw that Exception since the lock() method guarantees the record existence before it's being locked. This dilemma raises the follwoing scenarios:

1. unlock() method should throw RecordNotFoundException if the record doesn't exists in the database file, (that means we will never be able to unlock records that we locked, and then deleted coorectly)
consider this scenario:


long cookie = data.lock(3);
data.delete(3, cookie);
unlock(3, cookie) //Opps, RecordNotFoundException is thrown,Illogical!




2. unlock() method should throw RecordNotFoundException, if the data structure that holds references to the locked records doesn't conatin the record in question.
This semantic contradicts the lock() method logic, lock() method adds the record to the data structure and there is no way on earth that a re-search for the record fails.....Unless we allow two threads to modify the same locked record (very wrong)

3. A final resolution, is to make the CRUD methods that modify the file unatomic, meaning:

//very bad implementation of update
public void update(int recNo, String[] data, long cookie) {
//update the record
unlock(recNo, cookie);//ugly,we may still want to update the same record!
}


Please enlighten me guys, everytime I think I am done something comes up.

Hatim
Samuel Pessorrusso
Ranch Hand

Joined: Jul 21, 2005
Posts: 164
I solve this problem automatically unlocking a record when it is deleted; be sure to document your solution.
hatim osman
Ranch Hand

Joined: Jun 10, 2005
Posts: 105
Hi there....
thanx for replying, but will you please explain your approach further. Did you mean that the unlock() method is called from within the delete method?

I solve this problem automatically unlocking a record when it is deleted; be sure to document your solution.



because if you meant this:



Now if any thread attempts to unlock a record that it
previously locked, a SecurityException would be thrown, which shouldn't be case, the following sequence shouldn't produce errors :

-lock a record
-delete the record "should not unlock the record implicitly"
-unlock the record "fine, no errors should be produced


This way,the Data class will be very much independent on the way you solve your problem, remeber that this class should be portable across different applications; you should design the class in a way that it can be plugged into another application without any extra code. Please, correct me if I am wrong.


thanx in advance
Hatim
hatim osman
Ranch Hand

Joined: Jun 10, 2005
Posts: 105
Hi there...
I followed the 24 hours rule Andrew that's why I posted again.
Finally, I decided to do the following:

I considered that the RecordNotFoundException is not meant as an indication of the unexistence of the record rather to indicate that the record is not locked in the first place, validation of the cookie follows if and only if the record is locked. Therefore, I created RecordNotLockedException a subclass of RecordNotFoundException. Thus, this new exception can be easily thrown from the unlock() method, and exception handlers can still deal with it by catching the super class RecordnotFoundException.
The question is, Does this violate the specification?

Thanx
Hatim
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11437
    
  85

Hi Hatim,

I don't think it violates the specification, however I don't see what this is gaining you. Even with this solution, you still have to deal with the case where calling the unlock() method after calling the delete() method. Creating a RecordNotLockedException does not change this.

This is one of those cases where there is no perfect solution - any solution will have some downsides. You just have to decide which of those solutions makes better sense to you, and go with it. Some of the choices are:
  • Have the unlock() method only throw RecordNotFoundException if the record is not locked. This is not implied by the provided interface documentation, so you would have to document it yourself so that the junior programmer knows what will happen when they call unlock() after delete().
  • Have the unlock() method throw RecordNotFoundException after unlocking the record. In my opinion this is a fairly ugly solution - I don't think you should be throwing an exception for something that you require the Data class user to do. But it does meet the specification.
  • Have the delete() method silently perform the unlock for you. Again, this is not implied by the provided interface documentation, so you would have to document it yourself so that the junior programmer knows that they don't have to call unlock() after delete(). It has the advantage of neatly sidestepping the RecordNotFoundException problem, but has the disadvantage of breaking the standard "lock() ... doSomething ... unlock()" paradigm.
  • Ignore the lock altogether - if the record stays locked, too bad, it is not like anyone can use it anyway (possibly unlock it if your create method reuses the space). But then what happens to any records waiting for that particular record?

  • There are probably other solutions as well. Choosing which one to use (and justifying it) is part of being a developer.

    Note: That last potential solution brought up a big (separate)issue that affects all possible solutions - what happens if you have two or more clients waiting on a record that just got deleted. That is, what happens if:
  • Client A locks record 5
  • Client B attempts to lock record 5 - goes into WAITING state
  • Client C attempts to lock record 5 - goes into WAITING state
  • Client A deletes record 5

  • No matter what solution you choose, shortly after step 4 clients B and C need to wake up and handle the change of circumstance appropriately.

    Having said that - if you do believe that you are handling this appropriately (preferably you have tested this), and you get the 44/80 locking score, please let me know.

    Regards, Andrew


    The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
    hatim osman
    Ranch Hand

    Joined: Jun 10, 2005
    Posts: 105
    Hi there,

    Thanx Andrew, now, I understand the issue very well. I will spin things in mind and see what is the most appropriate solution.

    Hatim
    hatim osman
    Ranch Hand

    Joined: Jun 10, 2005
    Posts: 105
    Hi...
    Thanx again Andrew, I studied your remarks very well, and was able to come up with a way out that is a combination of two of your advices. Here is my final product on how I am going to deal with exceptions thrown from the unlock() method, and locking in general:



    Thus, my lock() method ensures that we only grant locks on valid record no matter what. Hence, the unlock() method will not throw RecordNotFoundException because the record doesn't exists in the file but because it's not locked. in the first place, Your scenario, and more will be dealt with in the following fasion:

    SCENARIO 1
    1. Client A locks record 5
    2. Client B attempts to lock record 5 - goes into WAITING state
    3. Client A deletes record 5, automatically unlocks 5, should notify others
    4. Client B wakes up, locking fails because record not found
    5. Client A unlocks 5, Record not locked exception will be thrown "see 3"

    SCENARIO 2:
    1. Client A tries to unlock 5, without previous lock ----> Record not locked exception

    SCENARIO 3:
    1. Client A lock 5
    2. Client A unlocks 5, fine no problem

    SCENARIO 4:
    1. Client A locks 5
    2. Client A updates 5
    3. Client A unlcoks 5, fine no problem

    And finally:
    1. Client A locks 5
    2. Client A deletes 5, automatically unlocks 5, should notify others
    3. Client A unlocks 5, Record not locked Exception

    Note, that the RecordNotLockedException is just the RecordNotFoundException with message "Record Not Locked". I also studied the issue of deadlocks, and ensure that the crude methods that need to validate the cookie, will request locks in the following order:
    1. Get lock on dataStructure for validation, release
    2. Get lock on RAF, release
    3. Get lock on dataStructure to delete the entry, release "only applicable for delete method".

    I will document this and go on, if it's right of course. Your comments fellow developer?

    Thanx
    Hatim
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11437
        
      85

    Hi Hatim,

    Looks reasonable.

    Regards, Andrew
     
     
    subject: B&S: unlock() method