• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Connection Object for lock/unlock...?

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, I've been quietly following the discussion on lock/unlock.
In my project, (in progress) I have an object on client side called DBAccessor. DBAccessor is a facade. The Gui Controller always talks to DBAceessor which in turn speaks to a DataInterface object (local or remote).
DBAccessor.bookFlight(recordNumber) method calls the DataInterface.bookFlight(recordNumber);
In network mode the DataInterface object is an extention of UnicastRemoteObject.
DataInterface in this instance will eventually make a call LockManager.lock(recordNumber). In order to meet specs regarding client locking, I had thought that LockManager (singleton by the way) could return an Integer object. Since the Integer object returned and the LockManager all live in the same VM when LockManager.unlock(recordNumber) is called the recordNumber passed could be the same Integer object that is returned from lock().
as so:
recNumInteger <- LockManager.lock(recordNumber);
:
:
LockManager.unlock(recNumInteger){
if(recNumInteger == recordNumberInHashSet)
then this client did lock this record so this client can unlock, else, did not lock this record, ignore unlock request.
The comparision is an object comparison...
Am I missing something here???
-Richard
 
Ranch Hand
Posts: 111
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good idea.
In order to solve the problem of identifying clients uniquely, your lock manager simply hands out a "ticket" and require that "ticket" to call unlock.
but, how do you let your unlock() method knows the Integer generated by lock() method?

laudney
 
Richard denSeig
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Laudney,
LockManager is known only to DataInterface (actully only to RemoteDataInterface).
When RemoteDataInterface.bookFlight() is invoked it will call the singleton LockManager. To lock a record, LockManger is passed an int which it converts to Integer. This object is then put as value in a "locks" HashSet and a reference to it (the Integer object) returned to RemoteDataInterface.
When RemoteDataInterface is ready to release the lock, it will call LockManager.unlock(Integer r) where r is the reference passed to it from the lock method.
(Yes, I have change signature of lock to return an Integer and signature of unlock to accept Integer arg.)
Since RemoteDataInterface and LockManager exist in the same VM the Integer reference should be valid...ie it should be matchable when LockManager performs its comparisons on Integer objects in the locks HashSet.
This is as much a question, as an explanation.
If I have forgotten something please clue me in.
In my design, DBAccessor is client side and speaks to a DataInterface that is returned from Factory. In this case the DataInterface is the RemoteDataInterface. RemoteDataInterface will return to DBAccessor is boolean: yeah, you booked the flight, or no, you did not.
The gory details of how a flight is booked is known and managed by RemoteDataInterface which does the calls LockManager.lock, read, write, and LockManager.unlock of the record.
However, I am not sure of the access of the read and write. Per the spec. these are public and therefore part of the DataInterface which the actual object implementing RemoteDataInterface implements. In my thinking this is a mistake as DBAcessor could call write, read directly on RemoteDataInterface object (untrustworththy client).
-Richard
 
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Richard:
Your design is similar to mine. You don't have to return the Integer object when lock(recNo) is called. You know the record number that you pass to the lock method. You can pass the same record number (primitive int) to the unlock method. In the unlock method, you can create a new Integer object with the primitive int to match against the Hashset. It should work fine. I am using Hashtable.
Also in my design, client makes seperate call to lock, read, modify and unlock.
 
Richard denSeig
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ummmm...I just read an old post that makes me doubt the wisdom of the approach I speak of above...
Peter den Haan says in post of 15 October 2001:


When your RMI connection breaks and your server attempts to clean up its locks the server must attempt to unlock ALL locks because it does not really know which record(s) your connection actually locked. Correct?
No. You must track client identity to satisfy the requirement that a client may lock() a record twice without ill effect. The identity tracking will also help clean up exactly those locks held by the now-defunct client.


In the approach I was thinking of you can tell if client locked the record they are requesting the unlock for...but, you cannot tell what records they have locked in case they attempt to lock the same record twice...
The light bulb begins to flicker...
 
Richard denSeig
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Sai,
The approach I had taken was to use the Integer object as a means to tell if the client requesting the unlock actually was the client who had requested the lock in the first place.
I have been struggling with this for some time...the larger issue is how to associate a client with a lock...so as to know which client's can unlock which records and if a client is no longer connected, to know the locks the client may have set, should be removed if still set.
So, I am back to trying to figure out how to "know" which client is setting the lock.
I have read here some people are using a connection object...but, my thinking cannot grasp how.
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ha! So my tenure as a bartender here has not completely been forgotten
Richard, your doubts are justified. You cannot fulfil all requirements if you don't have some way of associating a lock with a client.
To get your head around the connection object approach, read Mark's recent posts, or dig up some old ones from yours truly. Once it clicks, it's simple. Every client gets its own server-side Connection object to talk to; this object is its gateway to the database. From the lock manager's point of view, the Connection is the client identity. Assuming that your lock manager needs to map records to the client holding the lock on the record in question, this can be done using a Map mapping Integer record numbers to the Connection object for that client.
As an added bonus, implementing Unreferenced in the Connection gives you a three-line no-brainer way of recovering from client crashes. But don't worry about that for a start.
- Peter
 
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
Is it necessary to Map clients to records in the LockManager? If so should you use a WeakHashMap? If you don't use a WeakHashMap and the client dies, when will unreferenced() be called by RMI?
Thanks in advance
Michael Morris
 
Sai Prasad
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just one comment about Peter's posting. At any moment in this locking process, any one client will be associated with only one lock. So the Hashmap or Hashtable key should be the identifier for a particular client and not the record number.
Having said that, we could store the entire remote implementation object as the key for the Hashtable.
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Michael Morris:
Is it necessary to Map clients to records in the LockManager? If so should you use a WeakHashMap? If you don't use a WeakHashMap and the client dies, when will unreferenced() be called by RMI?

I will leave it up to you to decide whether you need a map or not - there is more than one "right" design.
There is no need for a WeakHashMap; unreferenced is invoked when there are no remote references to the object, even if it is still strongly reachable locally.
- Peter
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Sai Prasad:
Just one comment about Peter's posting. At any moment in this locking process, any one client will be associated with only one lock.

That is a dangerous assumption to make, especially in view of the reusability requirements for the database implementation. Surely future applications making use of the database might well need multiple locks.
But, as I said above, there is more than one "right" design, and making this assumption is unlikely to prevent you from passing the exam provided you set out your reasoning in the design documentation.
- Peter
[ April 10, 2002: Message edited by: Peter den Haan ]
 
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi folks,

Every client gets its own server-side Connection object to talk to; this object is its gateway to the database. From the lock manager's point of view, the Connection is the client identity. Assuming that your lock manager needs to map records to the client holding the lock on the record in question, this can be done using a Map mapping Integer record numbers to the Connection object for that client.


Peter, this "Connection Object Theorem" is still not clear, how can the server find out which Connection object it is dealing with when executing the unlock(int recN) code ??
Thanx
 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew,
As Peter and Mark have pointed out, if you implement a Connection Factory on the server and issue each client a unique connection object (that implments your DataAccess interface) then locked records can then be easily mapped to each client, which has a one-to-one relationship with the connection object. This approach certainly makes things a lot easier and clearer. I have totally changed my locking scheme (which was way too elaborate to account for ID's, timeouts, etc.) to use this approach. I personally don't think you have to Map clients to locked records in Data. If you keep up with locks in a HashSet in your connection object and only unlock those records, then the requirement to ignore an unlock request on a client who does not own the lock is achieved.
Hope this helps
Michael Morris
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Remember that the Connection object implements the DataInterface or whatever you've called it. That means that it implements lock() and unlock() too. In other words, the lock(int) method knows automatically what the client's identity is: it's "this", the current Connection instance!
Oh, I think I know where some of the bewilderment comes from... bad assumptions that are so easily made.
For example, do not assume that lock() and unlock() need to be implemented on Data. They are fine as they are. Yes, that means empty methods. Really! If you want to, you can flesh them out a bit by adding validation code for the record number, but the lock() and unlock() methods in Data do not need to implement locking at all.
Why not? Well, think a bit about what Data represents. It represents a local database that can only be used from a single JVM. It is a single-user database object that consequently should not try to implement any of the multi-user features, such as locking. Locking is part of a network-enabled, multi-user layer that is built on top of Data.
With a layered architecture such as this, you achieve clear separation of responsibilities, maximum ease of use (a developer only needs to deal with the multi-user networked stuff when (s)he needs a multi-user networked database) and the highest level of reusability.
So what the Connection object does is delegate calls to its lock(int) method to, for example, a LockManager instance that has a lock(int, Object) method, the Object being an object that identifies the client. In this case, the Object being passed in is... the Connection itself!
Does that clarify things?
- Peter
[ April 10, 2002: Message edited by: Peter den Haan ]
 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
Very clear. I hope you keep hangin' around here. It's nice to have another mentor to help us complete this certification.
Michael Morris
 
Andrew Collins
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now I understand !!
Thanks for explaining this one over and over again...
Just one question, any possibility Connection extends Data, I mean is Connection a.k.a. RemoteData ?
Michael, I hate to admit that I like your idea : implementing a lockedMap within the Connection Object ; I just finished my state-of-the-art LockManager
 
Andrew Collins
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Just one question, any possibility Connection extends Data, I mean is Connection a.k.a. RemoteData ?


Woops, shame on me !
Just pretend I never asked this please
 
Andrew Collins
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So what the Connection object does is delegate calls to its lock(int) method to, for example, a LockManager instance that has a lock(int, Object) method, the Object being an object that identifies the client. In this case, the Object being passed in is... the Connection itself!


Should I then wrap a Data object within Connection and delegate all method calls, except for lock and unlock ?
Thanks guys
 
Richard denSeig
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter (and others who are following and posting to this thread):
I have it now...Mark (kind soul) pointed me in the right direction...I never would have understood that the client can take an active role in locking...my thickhead could not imagine anything but a forceful server managing the locks and taking names...
Anyway, yes, your posts (and Marks...and others...don't want to leave anyone out) have been very instructive.
I do have another question/concern.
A class that implements an interface can throw fewer exceptions (of the same family) than the interface's method signature.
I have a root interface (DataInterface) and an interface RemoteDataInterface that extends DataInterface and Remote.
The exceptions dictated by DataInterface are DatabaseExceptions and RemoteExceptions.
The concrete class derived from DataInterface is Data (supplied by SUN) and throws DatabaseExceptions. The concrete class from RemoteDataInterface is RemoteData; it throws both Database and Remote exceptions.
I have a class on the client side, DBAccessor that knows about DataInterface and has an DataInterface member variable which becomes either a handle to Data (local mode) or RemoteData (remote mode). The RemoteDate is served to DBAccessor by a ConnectionFactory.
Wow...gets involved...my question, if you are still with me, is about the exceptions to be thrown in DBAccessor. Since DataInterface throws Remote for every method and Database for many methods, is there an *elegant* way to handle the exceptions that must be caught in DBAccessor.
I guess another way to ask this is there a clever way to handle the Remote and Database exceptions that must be caught regardless of mode (remote or local) due to the membar variable being of type DataInterface.
--Richard
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Andrew Collins:
Should I then wrap a Data object within Connection and delegate all method calls, except for lock and unlock ?

That's essentially it. You can add some bells and whistles -- for example, the Connection object could enforce that you must have a lock in order to modify a record, or perhaps even acquire and release a temporary lock if the client doesn't have one already. But in the assignment such frills are strictly non-essential.
The only other method that definitely isn't simply delegated to the underlying Data is close(). What the close() method should do generally is release all database resources held by the caller. For a local database (Data), that means closing the database file. For a remote database (Connection), that probably just means releasing any locks held by the client -- and certainly not that the database file is to be closed!
- Peter
[ April 11, 2002: Message edited by: Peter den Haan ]
 
Andrew Collins
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Peter and Michael,
You've been very supportive!
 
Andrew Collins
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi
Can you let me know if I'm right ? Thanx
My original design was :
db package
----------
- all classes provided by Sun
- DataInterface extends Remote throwing root Exceptions
- LockManager nested within Data
- Data implements DataInterface
server package
--------------
- RemoteDataImpl extends UnicastRemoteObject implements DataInterface throwing an additional RemoteException:
wraps a Data object
- Server : binds RemoteDataImpl to RMIRegistry
client package
--------------
- LocalDataImpl implements DataInterface throwing no RemoteException : wraps a Data object
- DataProxy implements Data, methods throw Exceptions : has 2 ctors : 1 for local, 1 for remote. Wraps LocalDataImpl or RemoteDataImpl depending on ctor of choice
As you can see I even used a LockManager in local mode since it was accessed via Data object
Also, changing the lock/unlock signatures was necessary
When I want to use a Connection Factory I have to :
DataInterface no longer extends Remote nor throws root Exceptions, just throwing DatabaseExc and IOExc.
RemoteDataImpl (this is the same as your Connection Object, right ??!!) no longer throws RemoteExceptions and wraps a Data object initialized by the connection factory (enters via ctor) (**)
- delegates lock/unlock to Singleton LockManager's lock/unlock
- implements serializable
RMIRegistry bound ConnectionFactory returning new RemoteDataImpl objects, packed with a reference to the Data instance(**)
Thanks
A
 
Ranch Hand
Posts: 94
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have been following the ConnectionFactory topic, but have a question.
The clients connection object implements the Data interface, but essentially lives on the server. does the connection objects stub count as the clients data client, with respect to the following requirement...
"To connect with your server, you should create a client program. This implementation should include a class that implements the same public methods".
Or do you think I need something like a RemoteDataClient that also implements the Data interface and wraps the stub to the server side Connection?
Your opinions are greatly appreciated. Thanks Dean
 
Sai Prasad
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Pl read the posting on the thread
 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys (and especially Peter and Mark),
I'm trying to get my wits around these two concepts of the ConnectionFactory/Connection, and the LockManager. I had no understanding at all of these until today, and have spent the day reading all the various posts. I know this has been hashed over a few times, but we all have our own way of seeing the world, so to speak, so I hope you'll humor me. This is what I've got so far:
1)FBNserver is started and binds a ConnectionFactory (which extends UnicastRemoteObject) to RMI.
2)ConnectionFactory's constructor creates an instance of Data (which implements DataInterface) and an instance of LockManager, and these are stored in member variables.
3)FBNClient is started and (only considering n/w impl) does a lookup on the ConnectionFactory.
4)FBNClient invokes a method in ConnectionFactory called getConnection, which creates and returns a new instance of Connection (which also extends UnicastRemoteObject and implements DataInterface). The references to the Data and LockManager objects are passed to the Connection constructor.
5)FBNClient now communicates with Connection for all its server needs. Most calls are passed through to Data. Lock and Unlock are not passed to Data, but instead are routed to LockManager, passing "this" (reference to Connection object) as argument along with recordNum. "this" allows LockManager to uniquely associate a client with a recordNum in a HashMap or Hashtable.
Is this the basic idea? ConnectionFactory creates one set of Data/LockManager objects per database table that will be needed by application, so these should not be singletons due to the need for extensibility.
Also, I do understand that ConnectionFactory doesn't necessarily need to create Data and LockManager from its constructor - it could just as easily do it the first time getConnection is called.
Please correct anything above that is weird. I'm a bit anxious on this topic as it is really new for me.
Thanks,
Debra Bellmaine
[ May 23, 2002: Message edited by: Debra Bellmaine ]
 
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Debra,
I think you got the general idea. I have a few comments:

2)ConnectionFactory's constructor creates an instance of Data (which implements DataInterface) and an instance of LockManager, and these are stored in member variables.

This will work (and I think that 95% of all people implemented it this way), but it's a bit inflexible. Instead of storing the instance of Data in member variable, how about storing instances of Data in a HashMap, along with the corresponding data file. That way, the server could be started with multiple databases, and the client can request any of them.
5)... Lock and Unlock are not passed to Data, but instead are routed to LockManager, passing "this" (reference to Connection object) as argument along with recordNum.
Although some people say it's OK not to implement lock() and unlock() methods, I have a problem with that. It looks to me that the requirements (implicitely) say that the lock/unlock must be implemented in Data. If it acceptable not to implement them in Data, why would Sun put them in there, just to confuse us? Also, if you do not implement locking for local mode, than your client cannot do a "lock-read-write-unlock" safely if multiple threads run this sequence (say, for some batch job reservation, or simply a new thread for the "Book" button to make GUI more responsive). In my implementation, I followed Mark's recommendation to do locking in Data, but to ignore the calls to unlock(), if the client didn't lock it (using the Connection mechanism).
Eugene Kononov.
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Debra I think you have it. Like Eugene there are some various flavors of this.
Eugene, I would like to say that I have been leaning more towards not implementing lock and unlock in the Data class, as time goes by, and I read more posts by Peter.
I don't think putting the Data class in the HashMap is necessary. I understand you point for extensibility for the future. But it is not needed now.

Also, if you do not implement locking for local mode, than your client cannot do a "lock-read-write-unlock" safely if multiple threads run this sequence


The is absolutely NO LOCKING in local mode. In local mode the app has exclusivity to the Data classes and db.db file.
Mark
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mark wrote:


The is absolutely NO LOCKING in local mode. In local mode the app has exclusivity to the Data classes and db.db file.


In local mode, the app does have exclusive access to Data and the file, but it does not negate the neccessity of locking (as I see it). If the app adds some functionality that can be run by multiple threads, we do need locking, do we not? We can, of course, synchronize the entire method that provides this functionality, but that may be too inefficient.
What am I missing here?
Eugene.
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

What am I missing here?


That this is supposed to be a simple application, and that you shouldn't over analyze it.
And that they specifically created local mode as a stand-alone program. If I am the only user, why should I lock a record. So I am the user and I go, hey I want to do something, can I get the lock. Yes, it's available, or no I can't because someone else has it, who oh me, I already have the lock.
Not needed at all in this assignment. Forget about one user creating multiple threads and each thread could change the data, and if two seperate threads try to change the same record, uh oh collision. If you create this assignment with multiple threads you are building the Taj Mahal for their requirements, and one of the requirements is keeping it simple so a junior programmer can understand it.
Please let me save you
Mark
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mark wrote:


Please let me save you.


I do want to be saved, but my Taj Mahal is 7 lines of code in Lock() of Data, and 2 lines of code in unlock() of Data. I do not even use LockManager. The "unlock() from foreign client" requirement is satisfied, the signature of the method is not changed, the access to Data is safe from local (single- or multi-threaded) and remote user, and the app is extendible for future enhancements. I am hoping for 155/155 :roll:
Eugene.
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Taj Mahal is 7 lines of code in Lock() of Data, and 2 lines of code in unlock()


So was mine, but a LockManager is a cleaner design, it decouples lock/unlock and users from the entire Data class.
And if you have any lock or unlock at all in local mode they will not give you 155/155.
Mark
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


And if you have any lock or unlock at all in local mode they will not give you 155/155.


How about this argument for implementing lock/unlock in Data class:
If you have an interface I, and classes A and B implement interface I, don't you think that it it is a bad design if one of the methods in I is not implemented (is empty) in either A or B? Just think of a java doc description for that method: "This method does nothing, it it here because Java Language Specification forced it".
If a class chooses to break the contract (or to pretend that it fulfills the contract), why have this class to implement that contract in the first place?
Hope some people will comment. I think I will also post this as a design question in some other ranch forum, just to have some diversity of opinion.
Eugene.
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
i have read this and other threads here, and im puzzled by some of the arguments here.
i have imeplemented lock/unlock in the data class as a hashmap with recordid as key and currentThread as value.
that way i can check for the client identity based on the executing thread.
im assuming some of you guys think this is a bad idea, and i would like some pointers.
the assmuption here (which i think is valid) is that all write operations lock->write>unlock is done in one method call from the client, and so would all run in the same thread?
oh and by the way, i DO need to change the signatures of the methods in the data class so they dont synchronize, right?
concering locking in the data class itself, the way i see it there is no good reason NOT to have locks in the db when its in local mode since i see it as an integrated part of a database that has nothing to do with whether it has remote clients or not
sincerely
morten wilken
 
Sai Prasad
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Marten:
the assmuption here (which i think is valid) is that all write operations lock->write>unlock is done in one method call from the client, and so would all run in the same thread?
Bad assumption. The sequence of operation may or may not be executed in the same thread. RMI doens't gurantee using a unique thread for every client.
concering locking in the data class itself, the way i see it there is no good reason NOT to have locks in the db when its in local mode since i see it as an integrated part of a database that has nothing to do with whether it has remote clients or not
I agree.
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can have a class that implements an interface, and doesn't implement one of the methods with actual code inside it's definition.
Like lock and unlock in the local access class. I must stress this. You are wasting resources if you have the local client in local mode call lock and unlock, and I am sure they will grade you lower.
Morton - like Sai said, RMI does not guarantee the same executing thread.
Mark
 
Ranch Hand
Posts: 234
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here are my thoughts on this thread:
Sai says that lock/unlock is an integral part of the database itself and should be implemented in the Data class.
Peter says that the Data class as given is a single-user database. He says that lock/unlock is part of the remote access layer built on top of the single-user database and that we should not be implementing it in Data.
Mark stresses the importance of not calling lock/unlock in local mode.
Here are my thoughts on the above:
1) I think that lock/unlock are a database feature, and that by implementing them in the remote access layer we are tying the two layers (db & remote) together. What if FBN grew, and they added more tables? Now we would have to change the remote access layer as well as the database layer. It's not necessarily more work, but I think we should be able to add a table without affecting the remote access layer.
2)How does a real database handle locking/unlocking of records?
3) Why not implement lock and unlock in Data and then defer the decision to call them (but not the implementation) to a different layer?
4) In reference to Peter's statement that Data represents a local database that can be only used from a single JVM, so its a single user database, consider the following: I could access the Data class from a servlet, and then have more than one user using it from one JVM.
Why not implement lock/unlock in Data, that way the database layer can be easily interchanged with different remote access layers?

What are everyone's thoughts?
-BJ Grau
[ May 26, 2002: Message edited by: BJ Grau ]
 
Sai Prasad
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is possible to implement LockManager and Data so that they can handle any number of tables in the future for lock/unlock with out any modification. This is how I implemented in my submission.
 
BJ Grau
Ranch Hand
Posts: 234
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sai -
I implemented lock and unlock in Data and with a LockManager like you did. In your application does lock get called for local access?
-BJ
 
Sai Prasad
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes. I have the same code for lock/read/modify/unlock sequence regardless of the mode.
 
BJ Grau
Ranch Hand
Posts: 234
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Do you think you lost points for this?
reply
    Bookmark Topic Watch Topic
  • New Topic