You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2011/04/07 12:00:15 UTC

svn commit: r1089795 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: dag
Date: Thu Apr  7 10:00:15 2011
New Revision: 1089795

URL: http://svn.apache.org/viewvc?rev=1089795&view=rev
Log:
DERBY-5158 Incomprehensible error message on client if attempting rollback after database has been shut down.

Scenario: app code calling client JDBC connection commit or rollback
after the database has been shut down. In the commit case the issue
and fix only applies if a transaction has been started, since
otherwise the client optimizes the commit away.

Patch DERBY-5158b, which corrects the protocol code on the client side
to cater for ENDUOWRM even in the error case (as sent by the
server). Looking at the DRDA standard, I managed to satisfy myself
that this is the correct behavior: section 7.5 Commit/Rollback
processing, where CR2 says:

"Application servers using remote unit of work protocols and
application servers using distributed unit of work but not protected
by a sync point manager must inform the application requester when the
current unit of work at the application server ends as a result of a
commit or rollback request by an application or application requester
request. This information is returned in the RPYDSS, containing the
ENDUOWRM reply message."

The "remote unit of work" is definitely ended, so...

Note that the (new) error stack trace is still different than with the
embedded driver, since there the 08003 will be directly reported as
the error (not wrapped in 06006 as shown below for the client side).

With this new code, on the client side, one can clearly see from the
exception stack that the underlying cause of the error is 08003. "No
current connection".

I added a new test, Derby5158Test.


Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java   (with props)
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java?rev=1089795&r1=1089794&r2=1089795&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java Thu Apr  7 10:00:15 2011
@@ -189,18 +189,15 @@ public class NetConnectionReply extends 
     private void parseRDBCMMreply(ConnectionCallbackInterface connection) throws DisconnectException {
         int peekCP = parseTypdefsOrMgrlvlovrs();
 
-        if (peekCP != CodePoint.ENDUOWRM && peekCP != CodePoint.SQLCARD) {
-            parseCommitError(connection);
-            return;
-        }
+        parseENDUOWRM(connection);
+        peekCP = parseTypdefsOrMgrlvlovrs();
 
-        if (peekCP == CodePoint.ENDUOWRM) {
-            parseENDUOWRM(connection);
-            peekCP = parseTypdefsOrMgrlvlovrs();
+        if (peekCP == CodePoint.SQLCARD) {
+            NetSqlca netSqlca = parseSQLCARD(null);
+            connection.completeSqlca(netSqlca);
+        } else {
+            parseCommitError(connection);
         }
-
-        NetSqlca netSqlca = parseSQLCARD(null);
-        connection.completeSqlca(netSqlca);
     }
 
     // Parse the reply for the RDB Rollback Unit of Work Command.
@@ -208,16 +205,16 @@ public class NetConnectionReply extends 
     // for the rdbrllbck command.
     private void parseRDBRLLBCKreply(ConnectionCallbackInterface connection) throws DisconnectException {
         int peekCP = parseTypdefsOrMgrlvlovrs();
-        if (peekCP != CodePoint.ENDUOWRM) {
-            parseRollbackError();
-            return;
-        }
 
         parseENDUOWRM(connection);
         peekCP = parseTypdefsOrMgrlvlovrs();
 
-        NetSqlca netSqlca = parseSQLCARD(null);
-        connection.completeSqlca(netSqlca);
+        if (peekCP == CodePoint.SQLCARD) {
+            NetSqlca netSqlca = parseSQLCARD(null);
+            connection.completeSqlca(netSqlca);
+        } else {
+            parseRollbackError();
+        }
     }
 
     // Parse the reply for the Exchange Server Attributes Command.
@@ -878,11 +875,16 @@ public class NetConnectionReply extends 
 
         netAgent_.setSvrcod(svrcod);
         NetSqlca netSqlca = parseSQLCARD(null); 
-        netAgent_.netConnection_.completeSqlca(netSqlca); 
-        agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_,
-            new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED),
-            msgutil_.getTextMessage(MessageId.CONN_DRDA_CMDCHKRM),
-            new Exception(netSqlca.getSqlErrmc()))); 
+        netAgent_.netConnection_.completeSqlca(netSqlca);
+
+        agent_.accumulateChainBreakingReadExceptionAndThrow(
+            new DisconnectException(
+                agent_,
+                new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED),
+                msgutil_.getTextMessage(
+                    MessageId.CONN_DRDA_CMDCHKRM),
+                new SqlException(agent_.logWriter_,
+                                 netSqlca)));
     }
 
 

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java?rev=1089795&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java Thu Apr  7 10:00:15 2011
@@ -0,0 +1,110 @@
+/*
+  Class org.apache.derbyTesting.functionTests.tests.jdbcapi.Derby5158Test
+
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to you under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+*/
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.sql.Statement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+
+
+public class Derby5158Test extends BaseJDBCTestCase
+{
+
+    public Derby5158Test(String name)
+    {
+        super(name);
+    }
+
+    protected static Test makeSuite(String name)
+    {
+        TestSuite suite = new TestSuite(name);
+
+        Test cst = TestConfiguration.defaultSuite(Derby5158Test.class);
+
+        suite.addTest(cst);
+
+        return suite;
+    }
+
+    public static Test suite()
+    {
+        String testName = "Derby5158Repro";
+
+        return makeSuite(testName);
+    }
+
+    protected void setUp()
+            throws java.lang.Exception {
+        super.setUp();
+        setAutoCommit(false);
+    }
+
+
+    /**
+     * DERBY-5158
+     */
+    public void testCommitRollbackAfterShutdown() throws SQLException {
+
+        Statement s = createStatement();
+        ResultSet rs = s.executeQuery("select 1 from sys.systables");
+        rs.close();
+        s.close(); // just so we have a transaction, otherwise the commit is
+                   // short-circuited in the client.
+
+        TestConfiguration.getCurrent().shutdownDatabase();
+
+        try {
+            commit();
+        } catch (SQLException e) {
+            if (usingEmbedded()) {
+                assertSQLState("08003", e);
+            } else {
+                // Before DERBY-5158, we saw "58009" instead with c/s.
+                assertSQLState("08006", e);
+            }
+        }
+
+
+        // bring db back up and start a transaction
+        s = createStatement();
+        rs = s.executeQuery("select 1 from sys.systables");
+        rs.close();
+        s.close(); 
+
+        TestConfiguration.getCurrent().shutdownDatabase();
+
+        try {
+            rollback();
+        } catch (SQLException e) {
+            if (usingEmbedded()) {
+                assertSQLState("08003", e);
+            } else {
+                // Before DERBY-5158, we saw "58009" instead with c/s.
+                assertSQLState("08006", e);
+            }
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/Derby5158Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java?rev=1089795&r1=1089794&r2=1089795&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java Thu Apr  7 10:00:15 2011
@@ -49,6 +49,7 @@ public class _Suite extends BaseTestCase
 		suite.addTest(ConcurrencyTest.suite());
         suite.addTest(DaylightSavingTest.suite());
 		suite.addTest(HoldabilityTest.suite());
+        suite.addTest(Derby5158Test.suite());
 		suite.addTest(LobLengthTest.suite()); 
 		suite.addTest(ProcedureTest.suite());
 		suite.addTest(SURQueryMixTest.suite());