Re: JDBC CTS 1.2.1 - Mailing list pgsql-jdbc
From | Vadim Nasardinov |
---|---|
Subject | Re: JDBC CTS 1.2.1 |
Date | |
Msg-id | 200411171506.13490@vadim.nasardinov Whole thread Raw |
In response to | Re: JDBC CTS 1.2.1 (Oliver Jowett <oliver@opencloud.com>) |
Responses |
Re: JDBC CTS 1.2.1
Re: JDBC CTS 1.2.1 |
List | pgsql-jdbc |
On Tuesday 16 November 2004 18:47, Oliver Jowett wrote: > It sounds like a bug in the CTS if it assumes it can run DDL (or for > that matter any query) in a transaction after a failure. This is not > specified by JDBC, AFAIK, and is demonstrably not a valid assumption > to make under PostgreSQL. > > Is there any way to tell the CTS to run each bit of DDL in a > separate transaction? I'm not sure. I (temporarily) patched the driver in a couple of places (see attached) and ran the tests in the ejb and jsp vehicles to try and figure out exactly where their behavior diverges. Initially, both vehicles call connection.setAutoCommit(false), like so: | at org.postgresql.jdbc2.AbstractJdbc2Connection.setAutoCommit(AbstractJdbc2Connection.java:598) | at com.sun.enterprise.resource.JdbcConnectionAllocator.createResource(JdbcConnectionAllocator.java:75) | at com.sun.enterprise.resource.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:150) | at com.sun.enterprise.resource.JdbcXAConnection.<init>(JdbcXAConnection.java:59) | at com.sun.enterprise.resource.JdbcConnectionAllocator.createResource(JdbcConnectionAllocator.java:83) | at com.sun.enterprise.resource.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:150) | at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:100) | at com.sun.enterprise.resource.JdbcDataSource.getConnection(JdbcDataSource.java:101) | at com.sun.enterprise.resource.JdbcDataSource.getConnection(JdbcDataSource.java:66) | at com.sun.cts.tests.jdbc.ee.common.DataSourceConnection.getConnection(DataSourceConnection.java:39) | at com.sun.cts.tests.jdbc.ee.dbMeta.dbMeta1.dbMetaClient1.setup(dbMetaClient1.java:120) From this point on, the bevahiors of the ejb and jsp vehicles differ. The ejb vehicle does not make any further changes to the autocommit setting. The jsp vehicle does. It calls connection.setAutoCommit(true) like so: | at org.postgresql.jdbc2.AbstractJdbc2Connection.setAutoCommit(AbstractJdbc2Connection.java:598) | at com.sun.enterprise.resource.JdbcXAConnection$JdbcConnection.getCurrentConnection(JdbcXAConnection.java:507) | at com.sun.enterprise.resource.JdbcXAConnection$JdbcConnection.createStatement(JdbcXAConnection.java:254) | at com.sun.cts.tests.jdbc.ee.common.dbSchema.dropTables(dbSchema.java:196) | at com.sun.cts.tests.jdbc.ee.common.dbSchema.createTable(dbSchema.java:94) | at com.sun.cts.tests.jdbc.ee.common.dbSchema.createData(dbSchema.java:48) | at com.sun.cts.tests.jdbc.ee.dbMeta.dbMeta1.dbMetaClient1.setup(dbMetaClient1.java:123) This has the following effect. The method AbstractJdbc2Statement#execute(Query query, ParameterList params, int flags) has the following piece of code: if (connection.getAutoCommit()) flags |= QueryExecutor.QUERY_SUPPRESS_BEGIN; So, when the tests are run in the jsp vehicle, the QUERY_SUPPRESSION_BEGIN bit is toggled on. In the ejb vehicle, it is left unset. In org.postgresql.core.v2.QueryExecutorImpl, we have private void execute(V2Query query, SimpleParameterList parameters, ResultHandler handler, int maxRows, int flags) throws SQLException { // ... String queryPrefix = null; if (protoConnection.getTransactionState() == ProtocolConnection.TRANSACTION_IDLE && (flags & QueryExecutor.QUERY_SUPPRESS_BEGIN) == 0) { queryPrefix = "BEGIN;"; // ... } Since the ejb vehicle does not set the QUERY_SUPPRESS_BEGIN flag, the queryPrefix variable is set to "BEGIN;". The end result is that in the case of the appclient, jsp, and servlet vehicles, each statement is treated as its own transaction. This allows tests to proceed merrily despite the failure of DROP TABLE statements. In the case of ejb, each test runs in a single transaction which includes DROP TABLE statements. As soon as a "DROP TABLE" statement fails, the rest of the transaction goes up in flames and the test fails. Not sure if anything can be done about it. > If you can issue a SAVEPOINT before the DROP TABLE and ROLLBACK TO > SAVEPOINT on failure, it might work. But it seems unlikely you can > do this without modifying the CTS itself, and you'd need to use 8.0 > for SAVEPOINT support. Right. Moreover, Savepoint seems to only be present in jdbc3: org/postgresql/jdbc3/PSQLSavepoint.java As far as I can tell, CTS 1.2.1 is meant to be run against the RI of J2EE 1.2.1. The latter only works under JDK 1.3. It has a hard-coded version check. > It might be useful to have an option to make the driver > automatically generate SAVEPOINTs before each query (when autocommit > is off), and do ROLLBACK TO SAVEPOINT or RELEASE SAVEPOINT as > appropriate after the query completes. This gives behaviour more > like other DBs at some cost to performance (I wouldn't want it to be > on by default). Again, this would only work against an 8.0 server. Yes, this sounds like it may work. But, like I said, you'd have to go through some contortions to make CTS 1.2.1 work in this setup. It's probably possible to run J2EE 1.2.1 under JDK 1.3 while at the same time running CTS 1.2.1 under JDK 1.4 with a driver that supports savepoints. Alternatively, you could just say we're not even going to try to make CTS 1.2.1 pass. Vadim
Attachment
pgsql-jdbc by date: