Thread: [Proxool-developer] J2EE 1.2.1 compliance testing
UNMAINTAINED!
Brought to you by:
billhorsman
|
From: Alastair C. <ala...@ci...> - 2002-12-12 20:54:48
|
Dear All,
Yesterday I sent a report highlighting an error that occured when using
Proxool with Ci-Access, a product we have developed. It appears that
Proxool obtained the connection and yet threw a SQLException when a
statement was executed using that connection. In order to investigate
which product actually caused the problem, I today tested the Oracle
driver by itself, which passed most (but not all!) tests in the test
suite. I then tested with the Proxool and Oracle drivers, and found
that the test suite does have a strange problem with Proxool. I think
that it cannot find ConnectionPoolManager.class in this method:
public static ConnectionPoolManager getInstance() {
if (connectionPoolManager == null) {
synchronized (ConnectionPoolManager.class) {
if (connectionPoolManager == null) {
connectionPoolManager = new ConnectionPoolManager();
}
}
}
return connectionPoolManager;
}
Here's the test-suite log:
********************************************************************************
Beginning Test: testAllProceduresAreCallable
********************************************************************************
SVR: Using DataSource
SVR-ERROR:
SVR-ERROR: java.lang.NoClassDefFoundError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:115)
at org.logicalcobwebs.proxool.ConnectionPoolManager.class$(Unknown
Source)
at org.logicalcobwebs.proxool.ConnectionPoolManager.<clinit>(Unknown
Source)
at org.logicalcobwebs.proxool.ProxoolDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(DriverManager.java:512)
at java.sql.DriverManager.getConnection(DriverManager.java:172)
at
com.sun.enterprise.resource.JdbcConnectionAllocator.createResource(JdbcConnectionAllocator.java:72)
... and so on for a few pages...
Any ideas? I thought J2EE might need the full name, so will try that
and see what happens.
Regards,
Alastair Calderwood
"Save paper... don't print out stack traces!"
|
|
From: Alastair C. <ala...@ci...> - 2002-12-15 14:24:32
|
1 .class file is not found in .jar Thanks for your tip, Christian. I'll try with a different lock to see if that solves the problem. Out of interest has anyone else had this problem with the jar, or are you all using unjarred classes? I'll use them unjarred until this problem is solved. 2. Oracle maximum cursors exceeded error On Friday I reported that Oracle was producing an error for certain tests when tested with Proxool. The error was: SVR-ERROR: java.rmi.RemoteException: ORA-01000: maximum open cursors exceeded I have researched the cause of the problem in Oracle FAQ and it appears that Oracle's default maximum number of cursors (300) should be quite sufficient. Cursors are staying open only because the test suite does not close every PreparedStatement but instead relies on the close method of Connection, which with a plain driver (i.e. without a connection pool in front) would call finalize on the whole hierarchy. In a connection pool where connections are not really closed, and there is no reference to the hierarchy, this never occurs. Personally I'd say it was the application programmer's responsiblity to close PreparedStatements - not sure why they haven't done so in the tests - and in my opinion the failure of these tests is not too important, but others might have different points of view. My next test is to run via a remote-access application (Ci-Access) that does close PreparedStatements when a Connection is closed, so perhaps that will yield a better result Alastair Calderwood |
|
From: Bas C. <ba...@ci...> - 2002-12-15 22:51:22
|
Alastair Calderwood wrote: > 2. Oracle maximum cursors exceeded error > to the hierarchy, this never occurs. Personally I'd say it was the > application programmer's responsiblity to close PreparedStatements - not > sure why they haven't done so in the tests - and in my opinion the > failure of these tests is not too important, but others might have > different points of view. My next test is to run via a remote-access "[java.sql.Connection.close()] Releases a Connection's database and JDBC resources immediately instead of waiting for them to be automatically released" [J2SE API 1.3.1]. Proxool's implementation doesn't release any JDBC resources before the Connection is returned to the pool. This behaviour doesn't satisfy the quoted description, so it is a bug in Proxool. Perhaps there are cases when a lazy close() is more efficient then closing each resource immediately after usage (??) Kind regards, Bas Kind regards, Bas -- Bas Cancrinus -> ba...@ci... Software Architect Cipherware Ltd. -> http://www.cipherware.com |
|
From: Bill H. <bi...@lo...> - 2002-12-16 09:18:06
|
On Sun, 2002-12-15 at 14:24, Alastair Calderwood wrote: > Out of interest has anyone else had this > problem with the jar, or are you all using unjarred classes? I'll use > them unjarred until this problem is solved. I always test with unjarred classes... > Cursors are staying open only because the test suite does > not close every PreparedStatement but instead relies on the close method > of Connection, which with a plain driver (i.e. without a connection pool > in front) would call finalize on the whole hierarchy. In a connection > pool where connections are not really closed, and there is no reference > to the hierarchy, this never occurs. Personally I'd say it was the > application programmer's responsiblity to close PreparedStatements - not > sure why they haven't done so in the tests - and in my opinion the > failure of these tests is not too important, but others might have > different points of view. I was chatting with Christian on ICQ last night (btw, my ICQ is 119577180) and we decided to get the ProxyConnection to close all unclosed Statements when it closes. We can write a debug message to the log to say that we are closing it for the user. This will be easy enough. On Sun, 2002-12-15 at 22:51, Bas Cancrinus wrote: > Perhaps there are cases when a lazy close() is more efficient then > closing each resource immediately after usage (??) Don't know exactly what you mean by lazy close, but I suspect it's very similar to closing automatically during the ConnectionReset method that I'm proposing. --- Thanks for all your work on the compliance testing, Alastair. I think I'm right in thinking that if we fix the Statement closure and the JAR file thing we will have passed? Regards, Bill |
|
From: Martin C. <mus...@us...> - 2002-12-18 20:22:26
|
All. Just some questions about proxool and transaction maintenance is once a connection closed. Upon quick inspection of the source, I see that the close/cleanup procedure calls the setAutoCommit(true) the comment: "Setting autoCommit to true might well commit all pending transactions. But that's beyond our control." Does this imply that JDBC drivers are mandated to reset the transaction, commit it, or just do whatever they feel is best? Is this the only transaction maintenance performed? Should proxool, perhaps be forcing a commit or rollback? Perhaps this should be a property setting to commit or rollback as a default once closed? Granted doing the commits and rollbacks is really required diligence on the programmer, but one stray transaction could really mess up consistency and block other transactions on the database. Additionally, I could not find anything in the JDBC API about determining if a transaction is currently running, anyone know anything? Just some more details from the field. Martin |
|
From: Bill H. <bi...@lo...> - 2002-12-18 23:33:31
|
Martin, On Wed, 2002-12-18 at 20:32, Martin Crawford wrote: > Just some questions about proxool and transaction maintenance is once a > connection closed. Upon quick inspection of the source, I see that the > close/cleanup procedure calls the setAutoCommit(true) the comment: "Setting > autoCommit to true might well commit all pending transactions. But that's > beyond our control." Does this imply that JDBC drivers are mandated to reset > the transaction, commit it, or just do whatever they feel is best? We've agonised a lot over this and haven't taken the decision lightly. To justify resetting autoCommit to true imagine the situation where two separate components share the same pool and the first one leaves autoCommit as false (which is perfectly acceptable, at least in theory). Then the second one gets a Connection and wonders why nothing actually gets committed. This is the sort of error that won't crop up in unit testing and could be a real devil to track down. That's exactly what we want to avoid. Our aim is to hand out connections as if they were new. But it turns out that that is an impossible task and we have to make some assumptions. I couldn't find any documentation on what a JDBC Driver should do when a Connection is closed whilst a transaction is in process. If anyone finds anything that would dictate what we should do then I would be happy to adopt that. Perhaps we could do some empirical testing of some of the drivers and see what they do. Even then, I would hesitate to adopt something that wasn't specified. > Is this the only transaction maintenance performed? The ConnectionResetter class resets the following properties: autoCommit catalog readOnly transactionIsolation typeMap holdability > Should proxool, perhaps be forcing a commit or rollback? Perhaps this should > be a property setting to commit or rollback as a default once closed? That's a matter of debate. I would suggest that it isn't really our job. I would rather guide people into using a less ambiguous approach: namely, always calling commit or rollback. > Additionally, I could not find anything in the JDBC API about determining if > a transaction is currently running, anyone know anything? Yes, that would be nice. Then we could log a warning. We have three goals here (in order of importance): 1. Using Proxool should behave exactly the same way as using the delegate driver (only faster). 2. The state of a Connection from the pool should not be dependent on how another component returns it. 3. Closing a Connection in an ambiguous state should react the same way as closing the delegate Connection. It would seem that we are possibly failing on point 3 at the moment. I don't think configuration of commit() or rollback() is the answer. I hope. > Just some more details from the field. Keep it coming. If anyone can report on how their particular JDBC driver handles ambiguous closes (autoCommit is false, no commit or rollback) then that might give us an indication of what we should be doing. Certainly, if all common drivers perform a commit and Proxool does a rollback then at the very least we should be documenting that behaviour. A Connection Pool turns out to be a lot more complicated than I thought :) Bill |
|
From: Bas C. <ba...@ci...> - 2002-12-21 04:18:06
|
Bill Horsman wrote: > I couldn't find any documentation on what a JDBC Driver should do when a > Connection is closed whilst a transaction is in process. If anyone finds > anything that would dictate what we should do then I would be happy to > adopt that. Perhaps we could do some empirical testing of some of the > drivers and see what they do. Even then, I would hesitate to adopt > something that wasn't specified. Regarding a call to Connection.close() while a transaction is in progress as an 'unrecoverable error' satisfies the following statement: "The execution of a <rollback statement> may be initiated implicitly by an implementation when it detects unrecoverable errors. When such an error occurs, an exception condition is raised: transaction rollback with an implementation-defined subclass code" [1]. >>Should proxool, perhaps be forcing a commit or rollback? Perhaps this should >>be a property setting to commit or rollback as a default once closed? > That's a matter of debate. I would suggest that it isn't really our job. > I would rather guide people into using a less ambiguous approach: > namely, always calling commit or rollback. Reflecting the above statement to Proxool, ConnectionResetter.reset(...) should a) detect whether a transaction is in progress; b) if a) is true then call Connection.rollback(); c) call connection.setAutoCommit(true). Avoiding a) should be harmless, so just calling Connection.rollback(); connection.setAutoCommit(true); will do. BTW: I consider implied commits very dangerous and I'm surprised that Connection.setAutoCommit(true) doesn't throw an SQLException if a transaction is in progress. Regards, Bas -- Bas Cancrinus -> ba...@ci... Software Architect Cipherware Ltd. -> http://www.cipherware.com |
|
From: Bill H. <bi...@lo...> - 2002-12-21 07:15:17
|
On Sat, 2002-12-21 at 04:18, Bas Cancrinus wrote: > Reflecting the above statement to Proxool, ConnectionResetter.reset(...) > should > a) detect whether a transaction is in progress; > b) if a) is true then call Connection.rollback(); > c) call connection.setAutoCommit(true). > > Avoiding a) should be harmless, so just calling Connection.rollback(); > connection.setAutoCommit(true); will do. Sounds sensible to me. Regards, Bill |
|
From: Martin C. <mus...@us...> - 2002-12-21 16:57:13
|
> Reflecting the above statement to Proxool, ConnectionResetter.reset(...) > should > a) detect whether a transaction is in progress; > b) if a) is true then call Connection.rollback(); > c) call connection.setAutoCommit(true). > > Avoiding a) should be harmless, so just calling Connection.rollback(); > connection.setAutoCommit(true); will do. Without looking at the code carefully, might I suggest proxool tracker the life of a transaction (and satisfy the requirements of a) based on the autoCommit flag and whether statements have been executed with commit()/rollback() subsquently called (or not called) before Connection.close(). This might avoid potential poorly written JDBC drivers getting bunged up if rollback() is called without an active transaction. I agree also that maybe shouldn't be be proxool's concern. Additionally, I agree that proxool might be having to assume too much to track a transaction, which coul be dangerous. I really just thought I'd throw it out there for you guys to think about. Otherwise, this does sound like the most reasonable approach. Incidentally, on my servlet application I made a facade database pool with proxool just underneath. When my developers physically "return" the database connection and before I call Connection.close() I rollback() blindly, catching any exceptions. This has been working without incident, and should validate what you are proposing. Cheers. Martin |
|
From: Bill H. <bi...@lo...> - 2002-12-20 00:34:21
|
Alastair, I have just committed the changes for automatic Statement closing. Any Statements that remain open when the Connection is closed are closed automatically. There is a debug message too. I hope this helps the compliance testing. Regards, Bill |