wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Remote/local database design. Please comment this. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Remote/local database design. Please comment this." Watch "Remote/local database design. Please comment this." New topic
Author

Remote/local database design. Please comment this.

Marcos Motta
Ranch Hand

Joined: Apr 28, 2002
Posts: 56
Your comments, please.
This is my local/remote database design.
DataInterface: Declares RemoteException in all
methods. Provides access to the database, hiding
all details about the location of the database file
from its clients allowing the pluggable behaviour
required by the FBN gui client
Data class: implements DataInterface.
lock()/unlock() remains empty. criteriaFind() implemented.
RemoteDataInterface: Extends DataInterface and Remote.
ServerConnection: Implements RemoteDataInterface.
Keeps an internal reference to a DataInterface instance
delegating all method calls to it.
The implementation of lock/unlock keeps a list of
the locks granted to the client and uses this information
to prevent improper locking operations (double locking
or unlocking record not locked by it).
Implements Unreferenced to release all locks upon dgc finalization.
ServerInterface: extends Remote.
Has only one method "RemoteDataInterface connect()", wich returns
an instance of ServerConnection providing a
connection to the database.
DataServer: Extends Data and implements ServerInterface.
Implements the lock/unlock behaviour.
A method named startServer() explicitly exports the object
to RMI (using "UnicastRemoteObject.exportObject()")
and binds the object to the registry.
connect() returns "new ServerConnection(this)", where 'this'
is the target DataInterface that will receive all method calls.
In my design there is no such thing as 'LocalDataInteface'.
Clients of DataInterface must allways consider the possibility
of being dealing with a remote database and handle exceptions
apropriatelly.
I am not 100% sure about this, please comment:
"When making calls against a DataInterface, wich might be
a local or remote database, my gui client allways
catches IOExceptions, never RemoteException.
This way it is catching RemoteException as well because
it is derived from IOException.
Since I am writing a generic client, capable of handling local
or remote databases, the gui client code see things at a layer
of abstraction, above the local and the remote database."
[ March 16, 2003: Message edited by: Marcos Motta ]
[ March 17, 2003: Message edited by: Marcos Motta ]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

In my design there is no such thing as 'LocalDataInteface'.
Clients of DataInterface must allways consider the possibility
of being dealing with a remote database and handle exceptions
apropriatelly.

in Local mode there will never be a remote connection. It is a stand alone application, with no servers, hence no remote.
So you interface should throw Exception, so that the implementation classes can then throw the more appropriate Exceptions.
In all cases in my submission I then would wrap the Exception into a DataBase exception that would be thrown all the way up to the client, and displayed in a nice screen with a nice message regarding the exception. Now, the exception to the above in my submission, was when the Exception is for the Server, and the Client doesn't even exist at this time, so there is no client to pass it too anyway.
Other than that I think is sounds ok, I might have a question about your locking schema. In remote mode client A locks record 1, and client B locks record 2. Now client A tries to lock record 2. How does it know that client B has the lock already and client A should not be able to get the lock. I didn't see that in your design.
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
Originally posted by Marcos Motta:
Your comments, please.
DataInterface: Declares RemoteException in all
methods. Provides access to the database, hiding
all details about the location of the database file
from its clients allowing the pluggable behaviour
required by the FBN gui client
Data class: implements DataInterface.
[ March 16, 2003: Message edited by: Marcos Motta ]
[ March 17, 2003: Message edited by: Marcos Motta ]

I am curious about your statement above. If DataInterface throws RemoteException in all methods, and Data implements it, then have you modified the methods in Data to throw RemoteException?
-BJ
Marcos Motta
Ranch Hand

Joined: Apr 28, 2002
Posts: 56

I might have a question about your locking schema. In remote mode client A locks record 1, and client B locks record 2. Now client A tries to lock record 2. How does it know that client B has the lock already and client A should not be able to get the lock. I didn't see that in your design.

I keep lock information in two lists: one at ServerConnection and other DataServer. Each client is attached to a ServeConnection wich in turn references the single DataServer instance (the only one that accesses the database file). ServerConnection keeps a list of locks granted to its associated client. DataServer keeps a list of locks granted to all clients. When client A tries to lock record 2, DataServer.lock() verifies that the record is already locked (already in the list) and puts the thread in wait until client B releases it. I decided not to implement a 'LockManager' because the locking mechanism is very simple and can be implemented entirely in my DataServer class. I could not see any benefit in creating LockManager because I will not reuse its functionality and it will not help in making code clearer. I am afraid that many will disagree.

But the Exception issue.... This is driving me nuts.

So you interface should throw Exception, so that the implementation classes can then throw the more appropriate Exceptions.

Do you mean I should do this?:
package suncertify.db;
public interface DataInterface {
public unlock() throws Exception;
public DataInfo getRecord() throws Exception;
...
}
public interface RemoteDataInterface
extends DataInterface,Remote { };
public class ServerConnection
implements RemoteDataInterface {
public unlock()
throws Exception, RemoteException { }
public DataInfo getRecord()
throws DatabaseException,Exception { }
}
package suncertify.gui;
DataInterface d;
...
try {
d.getRecord()
} catch(Exception e) {
handleException(e);
}
...

What am I missing?
Marcos Motta
Ranch Hand

Joined: Apr 28, 2002
Posts: 56

BJ Grau wrote:
I am curious about your statement above. If DataInterface throws RemoteException in all methods, and Data implements it, then have you modified the methods in Data to throw RemoteException?

Yes. I modified Data to throw RemoteException in all methods. And I am not confortable with it, but my point is: Data is an implementation of DataInterface wich is solely a means of allowing clients to work with remote or local databases using common interface.
If the gui client has to treat local and remote databases the same way through DataInterface, then RemoteException is a fact and must be considered in all points where de database is accessed. I decided not to implement the "local only" database access because I could not find a situation where the FBN application would require it. My assingment does not tell me to write a reusable database package, that would certainly have to treat the local only scenario.
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
Originally posted by Marcos Motta:

Yes. I modified Data to throw RemoteException in all methods. And I am not confortable with it, but my point is: Data is an implementation of DataInterface wich is solely a means of allowing clients to work with remote or local databases using common interface.

Data by tislef has nothing to do with remoteness, so I think it would be a bad design choice to do that.
How about this:
Make DataInterface match the method signatures of Data as supplied by Sun. Then write an adapter that allows clients to interact with RemoteData as if it was a DataInterface. So now your clients get a reference to DataInterface, and the actual concrete implementation is either simply Data for local access or RemoteDataAdapter with the adapter class passing along method calls to the contained RemoteData and converting the RemoteExceptions to the appropriate types.
or you can follow Mark's advice of the interface throwing Exception in each method.

-BJ
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

"try {
d.getRecord()
} catch(Exception e) {
handleException(e);
}
...

What am I missing?
"
Well you don't want to catch Exception in your client clode. While the interface throws Exception, the implementing class will throw a more specific exception. For intance in Remote implementation you will have to throw some RemoteExceptions/IOExceptions, but in your client you don't to even catch those. You would rather catch Application specific Exceptions.
So what I did was to catch the IO or RemoteException in the remote implemenation, create a DataBaseException that had a nice message in it for the user, then throw that up to the client, then in the client I would show that message in a nice popup screen.
Does this make sense?
Mark
Marcos Motta
Ranch Hand

Joined: Apr 28, 2002
Posts: 56
Do you think I can change the method signatures of the Data class supplyed by Sun? I think that I will have to do so in order to make it remotable.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Well you don't have to make the Data class remoteable, because if in remote mode it stays on the server and there is only one instance for all users. and in local mode there is no remote.
Your implementation of your Data interface for Remote will be remotable though.
Mark
Marcos Motta
Ranch Hand

Joined: Apr 28, 2002
Posts: 56
Please check this out. This is what I am planning to do:
Create an interface with all public methods of the supplyed Data class: DataInterface.
The only changes I will do in Data class will be: 1) add "implements DataInterface" to the class declaration; 2) replace the deprecated methods; and 3) implement criteriaFind().
Create a remotable interface called RemoteInterface having the same methods as DataInterface and declaring in all methods.
At the server side I will create an adapter class class called called ServerConnection implementing RemoteInterface and delegating all calls to an internal DataInterface.
The gui client will use DataInterface to access the database, no matter the execution mode (local or remote).
At the gui client side I will create another adapter class called RemoteDataConnection. RemoteDataConnection implements DataInterface and delegates all calls to an internal moteDataInterface.
When the client is in the localmode, it will be using an instance of Data class, otherwise a RemoteDataConnection, wrapping a RemoteDataInterface, will be used. I will have some kind of "connection factory" responsible for the creation of the DataInterface compatible with the execution mode.
I have a problem here: When wrapping RemoteDataInterface in RemoteDataConnection how am I going to bubble RemoteException up when it is catched inside a method that does not declare any exception on its signature (like unlock()) ? I dont think I should swallow it.
Oops! Back to the drawing board.
I think that my mistake was the choice of DataInterface as the one used by the gui client to access the database. The way I described it, DataInterface does not correctly express all the things that might happen on both execution modes (an exception thrown during unlock() for instance).
What if I: 1) declare "only" DatabaseException in all DataInterface�s methods (remove IOException from some of them) ; 2)remove the "implements DataInterface" from the Data class; 3) ServerConnection will delegate calls directly to an instance of Data; and 4) when calling methods in RemoteDataInterface, RemoteDataConnection will catch(Exception) and will throw all exceptions wrapped inside an new instance DatabaseException; and 5) I will create LocalDataConnection implementing DataInterface and delegating all calls to an instance of the Data class.
[ March 20, 2003: Message edited by: Marcos Motta ]
 
Consider Paul's rocket mass heater.
 
subject: Remote/local database design. Please comment this.