----- Original Message -----
From: "Kevin A. Burton" <[EMAIL PROTECTED]>
To: "Campbell Boucher-Burnet" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Friday, March 08, 2002 3:11 PM
Subject: Re: [Hsqldb-developers] MORE The database is already in use by
another process


> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> "Campbell Boucher-Burnet" <[EMAIL PROTECTED]> writes:
>
> > Fred:
> >
> > I'm not sure I completely agree.  As long as the connections are all
inside
> > the same VM, jdbcConnection can garantee that requests for the same URL
all
> > share a single instance of the Database, which makes concurrent access
safe
>
> BTW... I also tweaked our connection pool to only use one instance... and
it
> still failed :(
>
> > (i.e. openStandalone is syncronized, and Database.execute() is
syncronized,
> > and instances against each distinct database are cached) and should not
result
> > in the "Database is un use by..." message:
> >
> >     private synchronized void openStandalone(String user, String
password)
> >      throws SQLException { dDatabase = (Database)
> >      tDatabase.get(sDatabaseName);
> >
> >  int usage;
> >
> >  if (dDatabase == null) {
> >      dDatabase = new Database(sDatabaseName);
> >
> >      tDatabase.put(sDatabaseName, dDatabase);
> >
> >      usage = 1;
> >  } else {
> >      usage = 1 + ((Integer) iUsageCount.get(sDatabaseName)).intValue();
> >  }
> >
> >  iUsageCount.put(sDatabaseName, new Integer(usage));
> >
> >  cChannel = dDatabase.connect(user, password);
> >     }
> > /*
> > NOTE:  I just realized a bug in the code above!!!  Relative "standalone"
> > urls are broken, since we do not cannonicalize the path before puting it
in
> > the hashtable.  Thus, if the current directory is changed inside the JVM
and
> > a new "standalone" url connection is requested in the relative form, a
> > connection to the previously opened instasnce will be returned until the
> > usage count against the relative url goes to zero.  This needs to be
fixed
> > or documented in a clear manner.
> > */
>
/*

> Hm... wasn't this only added in JDK 1.4?  It might be better to compute
absolute
> paths on startup.
> <snip/>

Sorry Kevin...I must be dense...wasn't *what* only added in JDK1.4?
Canonicalizing a path?  Switching the current directory away from the pwd at
the time the VM was invoked? ...?  Actually, I've never tried or thought
about changing the pwd, I just always assumed setting the system property
"user.dir" had some such effect...but looking at the source, the system
properties are filled in by a native method in java.lang.System, and putting
a system property has only the effect of changing the value in the
properties object associated with the key.  This seems kinda "hmmm..." to
me.  It it possible to change the working directory of the JVM process?  To
be honest, I've never really encountered the need to do this...I just made
an assumption, which I shouldn't have.  Needs a bit more reading up on, I
guess.

NOTE 2:  Another bug?...if openStandalone does not get a cache hit (i.e.
this is the first attempt to connect to the standalone url in question, then
it should *not* put the new database instance in the cache (hashtable
tDatabase) or up the usage count in iUsageCount until  *after*  "cChannel =
dDatabase.connect(user, password)" succeeds.  That is, a try { } block
should be put around this and the SQLException should be rethrown in the
case of a bad username/password combo, but the tDatabase and iUseage count
variables should not be updated (should be located *after* attempting to get
the cChannel in the try block).  Otherwise, an application could try to
connect to a database in standalone mode, fail, and yet theoretically keep
that database open forever (at least until the application is closed),
blocking all other apps from opening that database.

However, there are some other problems associated with this simple code
change:

The Database class has a finalize method that attempts to shut down the
database if it was not already explicitly shut down.  This is fine and
probably A Good Thing(tm).  But, if a connection attempt is the first
attempt and fails, it may have taken a while to start up the database (with
MEMORY tables or if recovery took place, a potentially large log may have
been processed) and if we simply abandon the new dDatabase reference (let it
be garbage collected), then it may also take quite some time to finalize
(since the database does not checkpoint the log immediatley after a recovery
startup), blocking further connection attempts against the related
standalone url (or staring up a server instance agasint it) until the
finalization has shut down the database completely.  Plus, we have wasted a
bunch of time for nothing, possibly to experience the same condition in a
short amount of time as the user attempts to correct the username/password
error and connect again.  I can see that the current order of caching is
good for cases where the first connection attempt fails and we quickly
correct and reconnect (the instance is still hanging around), but it leaves
us open to hard-to-understand or unexpected behaviour, for example: the
database files are on a network file system and someone tries to connect to
the database and can't understand why "The Database is in use by another
process," since everybody else claims they are not connected to that set of
database files (even though someone actually still is, via an unsuccessful
connection attempt, and just don't know it).

I suggest there is a good case for persisting user-oriented data using a
separate mechanism (a separate cache file containing a single table with
user names and (hashed) passwords? who knows...needs some thought to retain
ACID properly) so that a Database class instance can construct quickly,
process the first connection attempt quickly, and shutdown quickly if it has
not moved to the second and much more time-consuming stage (actually
mounting the specified database files) because the first connection fails in
standalone mode.  Obviously, for server modes, a full startup and mount
should take place before even the first connection attempt (although I have
experimented a bit with lazy init that postpones mounting the database files
until first connect, among other lazy initializations).  As an aside,
perhaps a method should be provided to cause orderly shutdown for the server
modes, separate from having to connect as an admin and issue the SQL
SHUTDOWN command.  It seems JBoss and several other J2EE and/or other
application server frame work providers (including some Apache
sub-projects?)  have already been forced to add this kind of functionality.
We should take a look at the needs of the user community and provide this
functionality in the form that seems to best suite people's needs.
*/

> > However, it should *not* be possible to have connections to the same
> > standalone database url from separate JVMs/OS processes.  Theoretically,
one
> > should get the "The Database is in use by another process" message every
time
> > an attempt is made by some process after another process successfully
makes
> > the first connection.
>
> OK... what about from multiple threads?  What if you have the save JVM but
> multiple threads in the above scenario?
>
> Oh... I see what you are saying... multiple VMs all starting standalone by
> themselves on the same on-disk DB.... right.
> <snip/>

Yes.  I don't think we state this clearly enough in the documentation.  It
seems the posts to Help on this issue are endless.  A quick synopis is in
order:


Server/WebServer mode:  unlimited socket-based connections to the instance,
but no interface provided to get local (in-process) connections as well

Should be provided, though, to acknowlege the fact that there are plenty of
folks that would like to run the server modes in-process and also be able to
get in-process connections.

Example:

Server server = new Server(args);

Connection internalConection = server.getConnection(user,password);

WebServer webServer = new WebServer(args);

Connection internalWebServerConection =
webServer.getConnection(user,password);

Or perhaps this could all be dispensed with via driver properties, as
described below...
---------------------------------

Standalone/Memory mode: unlimited direct (in-process) connections, but no
posiblility of socket-based connections.

Should also be provided.

Example,  via driver properties and via SQL, as in:

 getConnection("jdbc:hsqldb:path(file path or "." for pure memory
operation)[,[create=(true(default)|false(fail if not already
created))],[listen=(proto(hsql or
http):[addr(default:primaryAdapterInetAddress:][port(default:9001)]]])","usr
","passwd")

An interesting possibility this creates is network connections to a volatile
(memory mode) instance.

Like I stated in my post to Open Discussion, the Database class should be a
Server factory.

Anyway, I know none of the really helps the problem at hand, but once again:
would you let me know in more detail the particulars surrounding getting the
"in use" message?  It would be nice to set up the same environment,
reproduce the case, trace it through, get a full understanding of what is
going on and going wrong, and then nail it.

Cheers,
Campbell

> - --
> Kevin A. Burton ( [EMAIL PROTECTED], [EMAIL PROTECTED],
[EMAIL PROTECTED] )
>              Location - San Francisco, CA, Cell - 415.595.9965
>         Jabber - [EMAIL PROTECTED],  Web - http://relativity.yi.org/
>
> The dawn is rising on a new day!
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.0.6 (GNU/Linux)
> Comment: Get my public key at: http://relativity.yi.org/pgpkey.txt
>
> iD8DBQE8iSkdAwM6xb2dfE0RAhZpAKCnKN58ZdL++lJM53SC/ox6OuvLAwCg0Gkk
> XCm8PzG40INvCqvtxmZ1lmE=
> =0ps/
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> hsqldb-developers mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/hsqldb-developers
>


_______________________________________________
hsqldb-developers mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/hsqldb-developers

Reply via email to