• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to release lock when RecordNotFoundException Occurs?

 
Anthony Choi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My program doesn't work for the following case.

Thread1 gets CPU
acquires lock for recNo 1
Delete recNo 1
release lock

Thread2 gets CPU
acquires lock for recNo 1
Update recNo 1
throws RecordNotFoundException

Thread3 gets CPU
tries to acquire lock for recNo 1
but Thread3 never succeeds.

To resolve the problem I made my updateRecord to call unlock() right before it rethrows RecordNotFoundException, but it doesn't work.

Any suggestions?
 
Jethro Borsje
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your Thread2 should never have acquired the lock on recNo 1....
 
Alex Belisle Turcot
Ranch Hand
Posts: 516
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jethro Borsje:
Your Thread2 should never have acquired the lock on recNo 1....


And also make sure that whenever something goes wrong, you still unlock the record..
 
Alex Belisle Turcot
Ranch Hand
Posts: 516
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just re-read your post and notice you also asked "how".

I agree with the previous rancher, you could forbid locking a record when it doesn't exist.

If you still want to perform some cleanup operations in case of an exception, add a "finally" block where you unlock the record. This will get executed in all cases.

Regard,
Alex
 
Anthony Choi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jethro and Alex.

You were right I made a mistake there, and I fixed it. I tested my program with 1000 threads performing 1000 actions respectively, and it works great.

Now, I have another question.

When I call deleteRecord() or updateRecord() I have to do it as following.



I didn't include details but basic structure above. The point is that I know that my program works well iff the finally block exists, so I can make my DB work correctly. But, what happens when the SUN guys test mine? Won't the auto-tester mess up my program? Any thoughts? If any one of you doing B&S 2.2.3, how do you guys handle it? By the way, RecordNotFoundException must be thrown since the interface provided by SUN says so.
[ October 05, 2008: Message edited by: bk choi ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi BK

Please check your private messages for an administrative matter.

My personal opinion on your second question - as long as your deleteRecord and updateRecord methods meet the contract of the interface, then any automated testing can only test to that contract. Since the interface's contract does not allow for the record to become unlocked following an update, any automated tests would have to assume that it is still locked following the update.

As to your original question - I agree with both Jethro & Alex (I seem to agree with them a lot, even if I don't say it) that if the record did not exist, then your thread should not have acquired a lock on it. Given that, your 2nd bit of code (the try..finally code) may be calling unlock even though there is no lock. Where do you go from there? If unlock throws SecurityException, then you really should be catching it as well (and what do you do in the catch?) If unlock returns a boolean indicating whether it was unlocked, are you doing anything with that return value (if not, why not?)

Regards, Andrew
 
Liviu Carausu
Ranch Hand
Posts: 160
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Andrew,

My personal opinion on your second question - as long as your deleteRecord and updateRecord methods meet the contract of the interface, then any automated testing can only test to that contract. Since the interface's contract does not allow for the record to become unlocked following an update, any automated tests would have to assume that it is still locked following the update.


Do you also think that the deleteRecord should not unlock the record ?
Then the unlockRecord will fail in any case after the record is deleted.
Calling unlock on a deleted record is a nonsens in my opinion. What do you think ?
Thanks,
Liviu
 
Attila J�borszki
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you also think that the deleteRecord should not unlock the record ?
Then the unlockRecord will fail in any case after the record is deleted.
Calling unlock on a deleted record is a nonsens in my opinion. What do you think ?


Hello,

I think this is your decision.

My interface description says only that a RecordNotFound exception should be thrown if calling the unlock method on a (locked or unlocked) deleted record, but it says nothing about what should happen with the lock on a locked deleted record.

Maybe the lock should remain on that locked deleted recored ... but this idea should not break the rule: the lock method should drop a RecordNotFound on a (locked or unlocked) deleted recored ...

But you should document this decision.

Attila
[ October 11, 2008: Message edited by: Attila J�borszki ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Liviu Carausu:
Do you also think that the deleteRecord should not unlock the record ?
Then the unlockRecord will fail in any case after the record is deleted.
Calling unlock on a deleted record is a nonsens in my opinion. What do you think ?


Hi Liviu,

There are many ways of handling this, and I don't know that any of them are perfect. I doubt that you will fail on any of the choices, as long as you document your choice and whatever you choose does not cause problems for other connected clients.

So leaving the record locked is fine, as long as you notify any clients waiting on the thread that they should try to get the lock again (at which point they should get a RecordNotFoundException or similar).

Alternatively unlocking the record within the delete method is another viable alternative. Once again, this should result in other clients being told that you no longer have the lock, and when they attempt to acquire it then they will get an appropriate error.

Alternatively setting your logic in your unlock method such that it attempts to unlock a held record before doing any other logic (such as record existence) can also work for you.

There are other options as well. See how many you can come up with.

By the way, the last time this was discussed, some members were tying themselves in knots worrying about how the delete method could call the unlock method without having an exception thrown. One option is to have the Data class a Fa�ade, calling other methods which may not throw the same exceptions.

Regards, Andrew
 
Liviu Carausu
Ranch Hand
Posts: 160
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Attila, Andrew
Thank you very much for your answers.
I was concerned about the workflow of the operations update and delete of the Data class. In my B&S application, I want to specify for the users of the Data class that a update operations must follow the lock-update-unlock flow but the delete operation only lock-delete. So that the user should not
call unlock on a deleted index. The unlock is done automatically,internally with deleting the record. Of course, without throwing any RecordNotFoundExceptions because internally I combine the methods of the two classes that are behind the Data Facade - a FileHandler and a LockManager.
A problem in my implementation will be waking up all the threads that are waiting at the delete record's lock. I normally do the unlocking of a record by waking up only one thread at a time. In this case all the waiting threads must be woken op to reevaluate their conditions....
Thanks once more, your answers were really helpful.
 
Attila J�borszki
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
So leaving the record locked is fine, as long as you notify any clients waiting on the thread that they should try to get the lock again (at which point they should get a RecordNotFoundException or similar).


Hi,

There is a rule for the lock method: "If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked."

If I leave the deleted record locked and I notify the waiting clients that they should try to get the lock again, I break the second part (no CPU cycles until the record is unlocked) of this rule ...

Or is this pedantry only and does not Sun take this rule so rigorously?

Attila
[ October 16, 2008: Message edited by: Attila J�borszki ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic