• 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
  • Devaka Cooray
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Jeanne Boyarsky
  • Tim Cooke
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
Bartenders:

B&S: unlock() method

 
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 164
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I solve this problem automatically unlocking a record when it is deleted; be sure to document your solution.
 
hatim osman
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
     
    hatim osman
    Ranch Hand
    Posts: 105
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 105
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Hatim,

    Looks reasonable.

    Regards, Andrew
     
    Roses are red, violets are blue. Some poems rhyme and some don't. And some poems are a tiny ad.
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic