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 (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. */ Now, since jdbcConnection.openStandalone and Database.execute() are synchronzied, and since jdbcConnection caches Database instances against local JDBC urls inside a syncronized section, it should be possible to safely have as many "standalone" mode connections as one likes inside the same JVM, against the same "standalone" hsqldb database url. However, as stated before, I still think there is some potential for problems, since it is not clear to me that the code in isAreadyOpen (and elsewhere?) actually does what is sets out to do 100% of the time. Also Log.open/close are called at other times besides startup and shutdown. In fact, it is unclear to me at the present exactly what orderings are ganarateed. As I stated several months ago, I find the Log and Cache classes to be written in somewhat more opaque a maner than I like. Even without the current issue, a rewrite is in order, IMO, so that future auditing and debugging efforts bear greater fruit. 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. However, I am not even sure that the current code can garantee this under every condition, on every platform, especially if there are several JVMs all attempting to startup/shutdown the database in rapid succession, as per the previous discussion of Log.isAlreadyOpen and suspected potential for race conditions. Of course, this is just speculation on my part that must be backed by a thorough audit of the related code and tests under the suspected platforms. Finally, if separate instances of the Database class are created directly and manipulated separately by user code (which, of course, must be located inside the hsqldb package, such as the super-server request handler factory/impl code we include in CVS), but not managed in the same spirit as jdbcConnection, then it cannot be garanteed that proper operation will occur, since each Database class instance maintains separate handles to the database files, separate copies of the Cache, memory table data, etc. Thus people writing modifications to the core code for use inside a super server raise the potential for unwanted effects, unless they pay close attention and ensure that connections to the same local disk-based url actually all go through just one Database class instance representing that url. I know that several products embedding hsql(db) have been forced to write modifications inside the org.hsqldb package for embedding in super server use cases, especially w.r.t. our broken implementation of SHUTDOWN. SEE: http://sourceforge.net/forum/forum.php?thread_id=647774&forum_id=73673 "The Database class should be a Server factory" Kevin: >OK... >I spent some type patching isAlreadyOpen and distributing updates .jar files to >my users. >Here is what I learned. >- - it isn't a synchronization issue in isAlreadyOpen. I created a synchronized block around Log.class and it still fails. >- - the file DOES exist. ***Would you please supply me a detailed description of the caseses and setup you are testing? I am interested in exactly what you are doing to produce the describe effect, and it is not totally clear to me from the descriptions so far. I could write a bunch of little tests myself in isolation, but I would rather completely understand what you are doing and try to reproduce it and nail this problem once and for all. Thanks in advance.*** > - the delete() == false call is what is causing this. > - canRead and canWrite both return true :( > think the problem is the way that the file is opened. Java states that on >some systems an open file is exclusive. >I think the problem is that on Windows, file operations in Java under Windows >are exclusive. Would you detail the gist of the execution trace that leads to this please, so I can fully understand? Obviously, I can't reproduce your setup and trace through it myself. >Maybe we should rewrite (make sense) Log.java to make sure that we don't try to >load the properties file while we are trying to save it. Looking at the current >code, it appears that someone could call open in one thread (DBConnection) while >isAlreadyOpen is trying to be called in another thread. See above...this should not be possible inside the same JVM, since openStandalone is syncronized, Database.execute() is syncronized, and there should never be two instances of Database that mount the same set of files ( although the converse..getting an instance against the wrong set of files for a relative url is possible, as outlined in my bug observation above). If I am wrong, would you be as kind as to detail a possible scenario that invalidates this assertion? >Under UNIX/Linux... these are not exclusive and at least from Java, there is no >way to make them operate so. >So... my thinking (no suggestion yet) is that we just use a static synchronizer >so that the properties file is not written to during another write/read >operation. >Does that make sense? It looks like we only have to modify isAlreadyOpen, >loadProperties and saveProperties... I think that makes sense. I think that was part of xclayl's general observations and contributed patches w.r.t. missing static synchs in the current codebase. Don't quote me on that, though. ;-) >As an aside. Could a DB connection pool raise this issue? It seems that it >might. I am using Turbine's DB connection pool with 20 connections. This >seems to work fine under Linux... obviously not find under Windows :) Sorry, I have no idea. I suppose that depends on whether the pool implementation goes through the existing hsqldb interface or has a part written inside org.hsqldb that attempts to do its own management of Database class instances. I presume the former, in which case it is our BAD. Sorry for the ignorance about Turbine. I'm sure it goes through the standard interfaces...I'm just trying to cover all the bases. >Kevin Cheers, Campbell. ----- Original Message ----- From: "Fred Toussi" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, March 08, 2002 2:20 AM Subject: Re: [Hsqldb-developers] MORE The database is already in use by another process > You are making several standalone connections to one database file. This is > safe only when the database is on a CD and set as read-only. > You should reduce the number of connections to 1. If the database (file) is > not corrupted, it is probably because your application uses the DB in an > atomic way and you are not using cached tables -- just consider it good > luck. > > Some information on different connection modes, written in two different > langauages (Campbell's and mine), can be found in the help forum. > http://sourceforge.net/forum/forum.php?thread_id=640842&forum_id=73674 > > Fred > > > > But in the meantime, re. connection pool with 20 connections? If these > > connections are to an HSQLDB server, they wouldn't be a problem, but if > they > > are standalone database connections, they definitely are THE problem. > > > > Your original message had: > > > > at org.hsqldb.jdbcConnection.openStandalone(jdbcConnection.java:926) > > It is jdbc:hsqldb:hypersonic/reptile > > > > > > _______________________________________________ > 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