Hi goeroes...,
I think it is better to start a new
thread for this :-)
After reading many discussions on the forum concerning the lock mechanism, whether or not to modify the Data.lock and .unlock signatures and the use of a lockmanager, I came up with the following (final ?) design:
EAch client recieves his own copy of the remote object FlightDataImpl, which encapsulates a FlightDataAdapter object.
There is, however, only one Data object, created in the RemoteConnectionFactoryImpl class and passed in to the FlightDataImpl constructor.
This makes it impossible to use the original Data.lock and unlock methods method without changing the signature. The data class has no knowledge of different clients and as there is only one Data object, the this identifier cannot be used for identifying the client who performed the lock.
Adding an extra parameter to the lock method for passing in a reference to the FlightDataAdapter class would be sufficient, but clearly violates the specs telling us to implement the original lock and unlock methods.
Therefore I started reading about the use of a lock manager, containing the static Map of locked records and the lock/unlock methods. The lock/unlock methods in the Data class remain useless because the Data class has no way of making difference between clients.
Therefore I leave the methods unchanged and empty.
In my new approach, I create a Data instance and a LockManager instance in the RemoteConnectionFactoryImpl constuctor.
The getConnection method creates and returns an instance of FlightDataImpl, passing both Data and LockManager instances.
The bookSeats method of FlightDataImpl now calls the lock.unlock methods as below:
The this parameter refers to the current FlightDataImpl object and IS unique for each client !
So we have transformed the locking actions to the remote object where they IMHO actually belong. When in local mode, we instantiate a DataAdapter object directly and we have nothing to do with the locking issue anymore.
The only remaining issue is that the DAta.lock/unlock methods are now void and unused. But is this really a violation of the specs ?
Further, because there is only one lockManager object, it is not useful to make the lockedRecords static. Am I right ?
I would be possible to make the LockedRecords a singleton because only one instance has to be created. A good idea ?
Any feedback in my final solution is very welcome !!!
Regards, Klaas
class FlightDataImpl<>-(1)------------(1)-> class FlightDataAdapter <>-(N)--------(1)-> class Data
extends UnicastRemoteObject implements FlightDataServices
implements FlightDataRemote, Unreferenced
--------------------
+ FlightDataImpl(data, lockManager)
+ bookSeats(recNum, seatsToBook)
---------------------------
class RemoteConnectionFactoryImpl
extends UnicastRemoteObject
implements RemoteConnectionFactory
---------------------------
-data : Data
-lockManager : LockManager
---------------------------
+ createConnection() : FlightDataRemote
(creates a Data and a LockManager object
and passes these to the FlightDataImpl
constructor)
---------------------------
class LockManager
- final Map lockedRecords = new HashMap();
+ lock(int record, Object owner) throws DatabaseException
+ unlock(int record, Object owner)
+ unlockAll(Object owner);
[ July 24, 2004: Message edited by: Klaas van Gelder ]
[ July 26, 2004: Message edited by: Klaas van Gelder ]
[ July 26, 2004: Message edited by: Klaas van Gelder ]