[
http://issues.apache.org/jira/browse/DERBY-1047?page=comments#action_12373702 ]
Kathey Marsden commented on DERBY-1047:
---------------------------------------
I have a fix for DERBY-1047 but now the original test case no longer fails and
I am having trrouble coming up with a new test case.
Firstly the problem description is not really correct:
The actual problem is that network server was closing the prepared statement
if an error occurred on execution (OPNQRY) , so a subsequent execution of the
prepared statement would fail. I am attaching the patch that fixes this
issue for reference but will wait until I have a test case to commit.
derby1047.patch
The reason the original repro no longer shows the issue is that the exception
that was used to invoke the issue (using a holdable statement in a global
transaction) no longer occurs, because the fix for DERBY-1158 makes this
legal. I thought that I would change the test case to have a lock timeout
instead and in fact the issue would ocur for regular connectiosn, but for
some reason that does not seem to provoke the problem. Attached are the old
and new test cases.
Derby1047.java - Old failing case (Doesn't fail anymore) : run
java -Dframework=DerbyNetClient Derby1047
UsePSAfterError.java - Attempt to write a new test case.
java -Dframework=DerbyNetClient UsePSAfterError
One other interesting thing to note is that this code to close the prepared
statement on statement execution error (OPNQRY error) seems to be new to
10.2. I do not see it in the 10.1 codeline. I am not sure when and why it
was added.
> [xa] With client xa, a PreparedStatement created before the global
> transaction starts gives java.sql.SQLException: 'Statement' already
> closed.' when used after the global transaction ends
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: DERBY-1047
> URL: http://issues.apache.org/jira/browse/DERBY-1047
> Project: Derby
> Type: Bug
> Versions: 10.2.0.0
> Reporter: Kathey Marsden
> Priority: Minor
>
> In checkDataSource there is a case where a statement is created outside a
> global transaction,
> the global transaction is started and ended and then the statement reused.
> In this case with client we can an error
> java.sql.SQLException: 'Statement' already closed. I will exclude this case
> and reference this bug number in the
> test
> Note: The server side error indicates the error occurs on session close, but
> I don't understand how the session is getting closed in this case. Also the
> test comments say a new underlying connection is created after xa_end, but I
> don't know what that means with regard to the statement prepared before the
> global transaction started.
>
> The code:
> PreparedStatement psParams = cs1.prepareStatement("select * from ru where i >
> ?");
> psParams.setCursorName("params");
> psParams.setInt(1, 2);
> resultSetQuery("Params-local-1", psParams.executeQuery());
> sruBatch.addBatch("insert into ru values 4");
> queryOnStatement("sru1-local-1", cs1, sru1);
> cs1.commit(); // need to commit to switch to an global
> connection;
> xid = new cdsXid(1, (byte) 103, (byte) 119);
> xar.start(xid, XAResource.TMNOFLAGS); // simple case -
> underlying connection is re-used for global.
> System.out.println("Expecting exception because global
> transaction sru1-global-2 is trying to use a statement with holdability
> true");
> queryOnStatement("sru1-global-2", cs1, sru1);
> sruBatch.addBatch("insert into ru values 5");
> Statement sru2 = cs1.createStatement();
> sru2.setCursorName("OAK2");
> queryOnStatement("sru2-global-3", cs1, sru2);
> System.out.println("Expecting exception because global
> transaction sru1-global-4 is trying to use a statement with holdability
> true");
> queryOnStatement("sru1-global-4", cs1, sru1);
> showStatementState("GLOBAL ", sruState);
> showStatementState("PS GLOBAL ", psruState);
> showStatementState("CS GLOBAL ", csruState);
> try {
> resultSetQuery("Params-global-1",
> psParams.executeQuery());
> System.out.println("FAIL: should have gotten exception
> because holdability is true on prepared statement and that is not allowed in
> global transactions");
> } catch (SQLException ex) {
> System.out.println("PASS: got exception because
> holdability is true on prepared statement and that is not allowed in global
> transactions");
> System.out.println(ex.getMessage());
> }
> xar.end(xid, XAResource.TMSUCCESS);
> // now a new underlying connection is created
> queryOnStatement("sru1-local-5", cs1, sru1);
> queryOnStatement("sru2-local-6", cs1, sru2);
> sruBatch.addBatch("insert into ru values 6,7");
> Statement sru3 = cs1.createStatement();
> sru3.setCursorName("SF3");
> queryOnStatement("sru3-local-7", cs1, sru3);
> // Two transactions should hold locks (global and the current
> XA);
> showStatementState("LOCAL ", sruState);
> showStatementState("PS LOCAL ", psruState);
> showStatementState("CS LOCAL ", csruState);
> resultSetQuery("Params-local-2", psParams.executeQuery());
> /// this is the line that failes with Statement alread closed.
> checkLocks(cs1);
> cs1.commit();
> The client error:
> getMaxRows() 85
> java.sql.SQLException: 'Statement' already closed.
> at
> org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:285)
> at
> org.apache.derby.client.am.PreparedStatement.executeQuery(PreparedStatement.java:301)
> at
> org.apache.derbyTesting.functionTests.tests.jdbcapi.checkDataSource.runTest(checkDataSource.java:514)
> at
> org.apache.derbyTesting.functionTests.tests.jdbcapi.checkDataSource.main(checkDataSource.java:133)
> Caused by: org.apache.derby.client.am.SqlException: 'Statement' already
> closed.
> at
> org.apache.derby.client.am.Statement.completeSqlca(Statement.java:1612)
> at
> org.apache.derby.client.am.Statement.completeOpenQuery(Statement.java:1283)
> at
> org.apache.derby.client.net.NetStatementReply.parseOpenQueryFailure(NetStatementReply.java:506)
> at
> org.apache.derby.client.net.NetStatementReply.parseOPNQRYreply(NetStatementReply.java:229)
> at
> org.apache.derby.client.net.NetStatementReply.readOpenQuery(NetStatementReply.java:59)
> at
> org.apache.derby.client.net.StatementReply.readOpenQuery(StatementReply.java:49)
> at
> org.apache.derby.client.net.NetStatement.readOpenQuery_(NetStatement.java:151)
> at
> org.apache.derby.client.am.Statement.readOpenQuery(Statement.java:1279)
> at
> org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:1685)
> at
> org.apache.derby.client.am.PreparedStatement.executeQueryX(PreparedStatement.java:307)
> at
> org.apache.derby.client.am.PreparedStatement.executeQuery(PreparedStatement.java:292)
> ... 2 more
> java.sql.SQLException: 'Statement' already closed.
> at
> org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:285)
> at
> org.apache.derby.client.am.PreparedStatement.executeQuery(PreparedStatement.java:301)
> at
> org.apache.derbyTesting.functionTests.tests.jdbcapi.checkDataSource.runTest(checkDataSource.java:514)
> at
> org.apache.derbyTesting.functionTests.tests.jdbcapi.checkDataSource.main(checkDataSource.java:133)
> Caused by: org.apache.derby.client.am.SqlException: 'Statement' already
> closed.
> at
> org.apache.derby.client.am.Statement.completeSqlca(Statement.java:1612)
> at
> org.apache.derby.client.am.Statement.completeOpenQuery(Statement.java:1283)
> at
> org.apache.derby.client.net.NetStatementReply.parseOpenQueryFailure(NetStatementReply.java:506)
> at
> org.apache.derby.client.net.NetStatementReply.parseOPNQRYreply(NetStatementReply.java:229)
> at
> org.apache.derby.client.net.NetStatementReply.readOpenQuery(NetStatementReply.java:59)
> at
> org.apache.derby.client.net.StatementReply.readOpenQuery(StatementReply.java:49)
> at
> org.apache.derby.client.net.NetStatement.readOpenQuery_(NetStatement.java:151)
> at
> org.apache.derby.client.am.Statement.readOpenQuery(Statement.java:1279)
> at
> org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:1685)
> at
> org.apache.derby.client.am.PreparedStatement.executeQueryX(PreparedStatement.java:307)
> at
> org.apache.derby.client.am.PreparedStatement.executeQuery(PreparedStatement.java:292)
> ... 2 more
> Exception in thread "main"
> The Server error in the derby.log
> 'Statement' already closed.
> SQL Exception: 'Statement' already closed.
> at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:80)
> at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:87)
> at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Util.java:166)
> at
> org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(EmbedConnection.java:1919)
> at
> org.apache.derby.impl.jdbc.ConnectionChild.newSQLException(ConnectionChild.java:163)
> at
> org.apache.derby.impl.jdbc.EmbedStatement.checkStatus(EmbedStatement.java:1247)
> at
> org.apache.derby.impl.jdbc.EmbedStatement.getFetchDirection(EmbedStatement.java:741)
> at
> org.apache.derby.iapi.jdbc.BrokeredStatement.setStatementState(BrokeredStatement.java:506)
> at
> org.apache.derby.iapi.jdbc.BrokeredPreparedStatement30.createDuplicateStatement(BrokeredPreparedStatement30.java:68)
> at
> org.apache.derby.jdbc.XAStatementControl.getRealPreparedStatement(XAStatementControl.java:127)
> at
> org.apache.derby.iapi.jdbc.BrokeredPreparedStatement.getPreparedStatement(BrokeredPreparedStatement.java:502)
> at
> org.apache.derby.iapi.jdbc.BrokeredPreparedStatement.getStatement(BrokeredPreparedStatement.java:509)
> at
> org.apache.derby.iapi.jdbc.BrokeredStatement.close(BrokeredStatement.java:130)
> at
> org.apache.derby.impl.drda.DRDAStatement.close(DRDAStatement.java:959)
> at org.apache.derby.impl.drda.Database.close(Database.java:301)
> at org.apache.derby.impl.drda.Session.close(Session.java:110)
> at
> org.apache.derby.impl.drda.DRDAConnThread.closeSession(DRDAConnThread.java:7106)
> at
> org.apache.derby.impl.drda.DRDAConnThread.run(DRDAConnThread.java:251)
> Apache Derby Network Server - 10.2.0.0 alpha shutdown at 2006-02-24
> 12:44:49.278 GMT
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira