wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes why lost so many points on locking Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "why lost so many points on locking" Watch "why lost so many points on locking" New topic
Author

why lost so many points on locking

Yan Zhou
Ranch Hand

Joined: Sep 02, 2003
Posts: 136
Hi,

I did pass the exam, but only got 44 out of 80 on locking. I did extensive test on my locking strategy and could not think of anything I missed.

My assignment is B&S. The following is some points in my design. I hope that someone could shed some light on what I might have missed in locking.

In my design, the DBMain() interface is exposed to GUI clients because the requirement expects a traditional client-server architecture.

When server/application starts up, all valid contractors are read from the data file and added into a cache called ContractorMap. It maintains a mapping between a record number and its values. This cache is at server-side, thus any change in cache is available to all clients. Any add/remove/update is first updated into the data file and then the cache.

I created a class ContractorDatafile that implements file I/O with synchronization, too. My data class uses the cache (to look up a record's values) and the ContractorDatafile (to write to file) classes.

=== LOCKING strategy ===

Multiple threads can simultaneously call on Data's public methods. Data class implements record locking by controling access to a list of marked records, a record is said to be marked if a client has exclusive update access to it. The list itself is the synchronized object. The following is record locking strategy:

1. A thread first acquires the lock on this list, then it checks to see if the record number it wants to update is already
on the list. If so, someone else is updating the record. The thread waits for a notification on the list.

2. After a thread finishes update, it acquires the lock on this list and removes the record number off the list.
It notifies all threads waiting on the list.

3. The waiting thread wakes up, acquires the lock, ensures that the record number is still available and is not on the
list, and it then adds the record number onto the list (thus marking the record).

4. The thread now has exclusive update access on the record.

Besides record locking in Data class, file access is also synchronized in ContractorDatafile class so that only one thread can write to the file at any given time. In addition, the cache ContractorMap also has synchronization since the mapping between record number and its value will be updated as records are updated/added/deleted.

Deadlock is prevented since under no circumstance would a thread trying to acquire a lock while holding on another lock.

=== END ===

Please note that after a thread acquires the lock, it again checks to make sure the record is still available, something you friends pointed out eariler.

In addition, I specified the following GUI clients' responsibility on locking:

1. Updating records:
We have required client program to correctly uses lock() and unlock() before and after calling update(), respectively. For example, the client must not call update() or unlock() without first successfully lock the record. This is guaranteed because we are writing the client code and there is no one else using the DBMain interface.

With this assumption, we do not worry about a client trying to unlock a record that is locked by another client, because all clients must use lock() and unlock() correctly.

2. Deleting records:
We have required that the client calls lock() before invoking delete(). However, since the record will have been deleted, there is no need to call unlock() after delete() returns.

3. Exception handling during update:
If client is catching an exception from server when calling update(), it must unlock the record. Otherwise, the lock is never released. The best way to do this is for client to wrap any call to update() with a try/catch/finally block and then call unlock() in the finally block.

We are not concerned about client crashing while holding the lock since the requirement does not say anything needs to be done on this. In a real world situation, we would have grouped lock/update/unlock into one method that is executed on server, which method is then exposed to client through a facade interface, this guarantees that lock/update/unlcok are executed in
one single remote call and there will be no need to worry about leaked locks.

=== END ===

What could I miss?

Thanks.
Yan
David Abramowicz
Ranch Hand

Joined: Dec 10, 2004
Posts: 56
I would also be very interested to know that actually, as my locking approach is very similar, and I am up for submit in a couple of days.

Frans Janssen
Ranch Hand

Joined: Dec 29, 2004
Posts: 357
Originally posted by Yan Zhou:
1. Updating records:
We have required client program to correctly uses lock() and unlock() before and after calling update(), respectively. For example, the client must not call update() or unlock() without first successfully lock the record. This is guaranteed because we are writing the client code and there is no one else using the DBMain interface.

With this assumption, we do not worry about a client trying to unlock a record that is locked by another client, because all clients must use lock() and unlock() correctly.


I don't know if this could be the reason for deduction, but I will not dare to make the assumption as stated above. I will be assuming that another ignorant or even malovent developer might create a client that does not play by the rules with regard to locking/unlocking. I will therefore design my server such that even an ill-designed client cannot disturb the database's integrity.

So my server will only allow updating, deleting and unlocking of records to a client that has acquired the lock on the record.

Frans.


SCJP 1.4, SCJD
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11278
    
  59

Hi Yan,

2. Deleting records:
We have required that the client calls lock() before invoking delete(). However, since the record will have been deleted, there is no need to call unlock() after delete() returns.


So what happens if two clients try to gain the lock simultaneously - one to do a delete and one to do an update? If the delete gains the lock first, and it is never unlocked, will the client who wanted to do the update stay in wait state forever?

If you do unlock the record, then you must also make sure that any clients waiting on the lock will re-check that the record has not been deleted (many people seem to forget that).

You haven't mentioned what you do with your create method - doing logical record locking may not make sense, but you must be doing something there.

I agree with Frans that your reasoning behind not validating who owns the lock is not very good. I don't think it fits in with the instructions provided in the comments in the interface you were provided.

Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11278
    
  59

Hi Yan,

One more comment - the 44 / 80 score for locking is very common. You might be interested in reading the post "The Mysterious 44/80 Locking score". It is deliberately a bit obscure, but might give you some hints.

You might also try looking for some of Anton Golovin's posts on the subject .

Regards, Andrew
Zhongbo Li
Greenhorn

Joined: Dec 06, 2003
Posts: 23
you are great,because you have been passed.


SCJP,SCJD,软件设计师<br />Skype:mediumwave<br />QQ:85646604<br /><a href="http://www.yjping.com" target="_blank" rel="nofollow">http://www.yjping.com</a>
Yan Zhou
Ranch Hand

Joined: Sep 02, 2003
Posts: 136
I did take care of multi-user scenario.

With delete(), my server internally "unlocks" the logical record, therefore, there is no need for client to do so. If a client is trying to update a record that is deleted, he will get an exception as specified in interface. I do re-check for availability of a record after getting lock.

The following is the spec. of the interface. As you can see, it says nothing that the impl. must ensure a client cannot unlock a record locked by another client. In fact, because the method signatures on update() and delete() do not take a session id, I do not see how I can track who gets the lock without extending the provided interface. My assumption is that if I have to extend/modify the interface from Sun, I might be doing more than what they wanted as many have emphasized to "keep it simple".

If my points are deducted because of not checking who is getting the lock, I would consider it as unfair.

However, I do not think I missed anything as far as locking is concerned.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: why lost so many points on locking
 
Similar Threads
My Locking Strategy...
(B&S):Lock cookie importance
Multi-threading programming: we do not need lock() unlock() at all
Architecture proposal
NX: Why do you all make LockManagers?