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