wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes NX: How to unlock(int recNo) after delete(int recNo) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "NX: How to unlock(int recNo) after delete(int recNo)" Watch "NX: How to unlock(int recNo) after delete(int recNo)" New topic
Author

NX: How to unlock(int recNo) after delete(int recNo)

Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35
Hello,
I'm thinking about the use of delete(int recNo). Please look at the following code.

Do you know a solution?
Thanks
Werner
Ken Krebs
Ranch Hand

Joined: Nov 27, 2002
Posts: 451
Werner,
Consider this: why should unlock throw RecordNotFoundException because the record was deleted ?
The fact that a record is locked is something that is totally separate from the record data itself.
kktec
SCJP, SCWCD, SCJD
"The journey is the reward."


kktec<br />SCJP, SCWCD, SCJD<br />"What we observe is not nature itself, but nature exposed to our method of questioning." - Werner Heisenberg
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
//this will throw a RecordNotFoundException
//because the record is deleted.

Perhaps that means you can't/shouldn't call unlock() on a deleted record.
//The record remains locked forever
//and causes deadlocks.

What record? It's been deleted, right? Any remaining traces of the record which might cause problems should be removed as part of the delete process, IMO. If another thread tries to do anything with the record after it's been deleted, they should immediately throw RecordNotFoundException. No deadlock.


"I'm not back." - Bill Harding, Twister
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Consider this: why should unlock throw RecordNotFoundException because the record was deleted ?
This may be a case where different assignments have different instructions. My own instructions make it clear that unlock() can throw RNFE, and that it should thorw this exception if it's called on a record that's been deleted. However other instruction may be different. So Werner, you'll have to decide what's appropriate for your own assignment, based on your instructions. These two posts should give you some ideas for options.
Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35

Consider this: why should unlock throw RecordNotFoundException because the record was deleted ?

Yim is right, my instructions require this behavior.

If another thread tries to do anything with the record after it's been deleted, they should immediately throw RecordNotFoundException

That's it. The recNo can't be used anymore and the the lock doesn't matter.
Thanks
Werner
[ November 22, 2003: Message edited by: Werner Joerling ]
Ken Krebs
Ranch Hand

Joined: Nov 27, 2002
Posts: 451
Werner,
My instructions also required throwing RecordNotFoundexception in both lock and unlock.
My point is that, at least in my implementation, they are not looking in the same place for the record. "lock" looks for the record in the normal place, in my case the Contractor list, and throws the exception if it can't find it there. "unlock" looks to see if a reference to the record number is found in the lock list and throws the exception if it can't find it there.
It's perfectly reasonable to make the "delete" method, as a special case, automatically do the the unlocking as Jim seems to suggest but it seems a little unnatural to me. A client invoking "lock" to protect an operation should expect to invoke "unlock" afterwards IMO.
kktec
SCJP, SCWCD, SCJD
"The journey is the reward."
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
"unlock" looks to see if a reference to the record number is found in the lock list and throws the exception if it can't find it there.
Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file.

Seems pretty clear. Perhaps Sun doesn't actually enforce this as written when grading assignments. I'd still prefer to err on the side of caution.
A client invoking "lock" to protect an operation should expect to invoke "unlock" afterwards IMO.
That's perfectly reasonable if we're designing the API ourselves - though it would be just as reasonable IMO to expect that once a record is "deleted" it's gone, with no further cleanup necessary. But we're not designing the API ourselves, so I'd have to advocate following the instructions provided. Even if it turns out that Sun doesn't actually enforce them.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Hmmm, there's also this quote from lock():
If the specified record is already locked by a different client, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked.

A literal reading here suggests that if a record is deleted but not unlocked, any waiting threads will now have to wait forever. :roll: Which seems rather inane. So I guess there's justification for bending the rules of in Sun's instructions somewhere here, and explaining it in your decisions.txt file. All right then, I withdraw my objection to Ken's solution.
Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35
Originally posted by Jim Yingst:
Hmmm, there's also this quote from lock():

A literal reading here suggests that if a record is deleted but not unlocked, any waiting threads will now have to wait forever. :roll: Which seems rather inane. So I guess there's justification for bending the rules of in Sun's instructions somewhere here, and explaining it in your decisions.txt file. All right then, I withdraw my objection to Ken's solution.

That implies the delete method must unlock the recNo and notify the waiting threads.
Then, one of the waiting threads
- adds recNo to the lockedRecords again (and notifies the waiting threads)
- calls one of the methods (read, update, delete) ... and gets RNFE
- eventually tries to unlock recNo ... and gets RNFE again
this repeats until there isn't any waiting thread.
Werner
[ November 22, 2003: Message edited by: Werner Joerling ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11490
    
  95

Hi Werner,
One alternative we have discused in this forum is to change the sequence for deletions, so it becomes: lock() ... delete().
Note that there is no call to unlock() there!
The way it has been suggested is that the unlock() and delete() methods could look something like:

Since the delete() method is now calling the private internalUnlock() method, all waiting threads will be notified that the record has now been released - no chance of them siting in the wait() loop forever.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
That implies the delete method must unlock the recNo and notify the waiting threads.
Well it doesn't have to imply that. You're assuming we can insert unlck() functionality into other method calls just because we feel it's appropriate, which may or may not be true. A more literal reading is that if you're waiting to lock a record, you wait forever. But that's a poor enough design that I'm willing to override a literal interpretation for what "common sense" says. Once we do that, well, why is my interpretation necessarily better than Ken's? I still prefer my interpretation, but I acknowledge that fundamentally Sun's specs here are broken, and if a programmer finds it necessary to bend those specs to make them work, there may be more than one way of bending them that is acceptable. I'm just acknowledging that, given the basic problems here with Sun's specs, Ken's interpretation is also a valid solution, IMO.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: NX: How to unlock(int recNo) after delete(int recNo)