db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r633778 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/impl/jdbc/ engine/org/apache/derby/impl/sql/conn/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/master/jdk16/ test...
Date Wed, 05 Mar 2008 06:03:31 GMT
Author: mamta
Date: Tue Mar  4 22:03:22 2008
New Revision: 633778

URL: http://svn.apache.org/viewvc?rev=633778&view=rev
Log:
I am backporting quite a few checkins from trunk into 10.3 codeline for DERBY-3304 and
DERBY-3404. 

The main functionality that is getting ported is when a user initiates a rollback through

JDBC Connection object, the rollback should not close the resultsets that do not return 
rows. 

This functionality was checked in into trunk through multiple checkins for DERBY-3304 and

those checkins are 628130, 629926, 631481. In addition, there was a supporting checkin into

trunk by Knut for DERBY-3404 (revision 629712) on which the 3 checkins listed earlier rely.

I am backporting all of these 4 checkins from trunk into 10.3 codeline.

The tests have run fine with no new regression.

I am including checkin comments for all these revisions for easy reference here. 
**********checkin comments for 628130)**************
DERBY-3304
DERBY-3037
DERBY-1585

I am adding a test case to check for the resultset from the java procedure call when the
java procedure has done a rollback inside it. This test shows that in trunk, after checkin
602991 for DERBY-1585, a procedure does not return a resultset if there was a rollbck
inside the procedure with resultset creation before rollback. This behavior is different
than what happens in 10.2 codeline. In 10.2, a procedure will return a *closed* resultset
if there was a rollback inside the procedure. But a procedure should not return closed
result sets, so it appears that trunk is behaving correctly and 10.2's behavior was
incorrect.
**********end of checkin comments for 628130)*******


**********checkin comments for 629712)**************
DERBY-3404: EmbedResultSet.getString() returns wrong value after auto-commit with 
CLOSE_CURSORS_AT_COMMIT
**********end of checkin comments for 629712)*******


**********checkin comments for 629926)**************
DERBY-3304

The main purpose of this patch is to fix the rollback handling for resultsets that do not
return rows. An example case for this is a java procedure which has a Connection.rollback
inside it. When the user calls the java procedure, and Connection.rollback is made inside
of it, Derby should not be closing the resultset assoicated with the java procedure call
(that resultset is a CallStatementResultSet). In other words, a user initiated rollback
through JDBC Connection object should leave the resultsets that do not return rows open. In
order to implement this, I had to make changes to ignore resultsets that do not return rows
in
GenericLanguageConnectionContext.endTransactionActivationHandling. As a result of this
change, for the eg case given above, the activation assoicated with the java procedure
will not be reset (which also means that, CallStatementResultSet.close will not be called)
inside GenericLanguageConnectionContext.endTransactionActivationHandling.

But the code inside CallStatementResultset.close() took care of the closed dynamic resultset
and it took out the closed dynamic resultset from the list of resultsets that would be
available to user through the Statement.getResultSet api. With my changes through this
patch, we are going to skip the CallStatementResultset.close during
GenericLanguageConnectionContext.endTransactionActivationHandling which means that we have
to deal with those closed dynamic resultsets on our own. I did that part of logic
changes in EmbedStatement.processDynamicResults

EmbedStatement.processDynamicResults used to check if the JDBC Resultset is closed by
directly checking the field isClosed in the EmbedResultSet. But it is not sufficient to
check only JDBC Resultset. We need to check the underlying language Resultset too to
determine if the dynamic resultset is closed. There is no direct api on EmbedResultset
which will return a boolean after checking the JDBC Resultset and language Resulset. Instead,
there is a method called EmbedResultSet.checkIfClosed. This method will throw an exception
if it finds the JDBC ResultSet or language ResultSet closed. So, my changes in
EmbedStatement.processDynamicResults make a call to EmbedResultSet.checkIfClosed and if
there is an exception thrown, then we know that the resultset is closed and hence we should
move to the next resultset.

In addition to these code changes, I have added a new test to LangProcedureTest. The new
java procedure is defined to return 2 dynamic resultsets. One of these resultsets is
created before Connection.rollback inside the java procedure. The other dynamic resultset
is created after Connection.rollback. As as result of Connection.rollback, the first
dynamic resultset will be closed but the second one will remain open. The test makes sure
that only one dynamic resultset is returned by the java procedure.

Also, made one minor change in LangProcedureTest for an existing test. The test at line 804
was getting a resultset from the Statement object without asserting that there are no more
resultsets. The resultset object would have been null anyways in this test because there
are no open resulsets from the Java procedure. Because of this, I took out the redundant
code of getting null resultset object from Statement using getResultset,
**********end of checkin comments for 629926)*******


**********checkin comments for 631481)**************
Checking in code cleanup for DERBY-3304. This code cleanup is based on Knut's review of my
earlier commit 629926. No functionality has changed, but code will be now much easier to
read.
**********end of checkin comments for 631481)*******



Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
Tue Mar  4 22:03:22 2008
@@ -2266,7 +2266,6 @@
 	//1)Make sure JDBC ResultSet is not closed
 	//2)Make sure this is an updatable ResultSet
 	//3)Make sure JDBC ResultSet is positioned on a row
-	//4)Make sure underneath language resultset is not closed
 	protected void checksBeforeUpdateOrDelete(String methodName, int columnIndex) throws SQLException
{
 
       //1)Make sure JDBC ResultSet is not closed
@@ -2277,13 +2276,6 @@
 
       //3)Make sure JDBC ResultSet is positioned on a row
       if (!isOnInsertRow) checkOnRow(); // make sure there's a current row
-      //in case of autocommit on, if there was an exception which caused runtime rollback
in this transaction prior to this call,
-      //the rollback code will mark the language resultset closed (it doesn't mark the JDBC
ResultSet closed).
-      //That is why alongwith the earlier checkIfClosed call in this method, there is a check
for language resultset close as well.
-
-      //4)Make sure underneath language resultset is not closed
-      if (theResults.isClosed())
-        throw Util.generateCsSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, methodName);
 	}
 
 	//mark the column as updated and return DataValueDescriptor for it. It will be used by updateXXX
methods to put new values
@@ -2299,7 +2291,6 @@
      * 1) Make sure JDBC ResultSet is not closed
      * 2) Make sure this is an updatable ResultSet
      * 3) Make sure JDBC ResultSet is positioned on insertRow
-     * 4) Make sure underneath language resultset is not closed
      */
     protected void checksBeforeInsert() throws SQLException {
         // 1)Make sure JDBC ResultSet is not closed
@@ -2313,11 +2304,6 @@
         if (!isOnInsertRow) {
             throw newSQLException(SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW);
         }
-
-        // 4)Make sure underneath language resultset is not closed
-        if (theResults.isClosed()) {
-            throw Util.generateCsSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, "insertRow");
-        }
     }
 
     /**
@@ -4276,7 +4262,21 @@
 	 * @exception SQLException		Thrown if this ResultSet is closed.
 	 */
 	final void checkIfClosed(String operation) throws SQLException {
-		if (isClosed) {
+		// If the JDBC ResultSet has been explicitly closed, isClosed is
+		// true. In some cases, the underlying language ResultSet can be closed
+		// without setting isClosed in the JDBC ResultSet. This happens if the
+		// ResultSet is non-holdable and the transaction has been committed, or
+		// if an error in auto-commit mode causes a rollback of the
+		// transaction.
+		if (isClosed || theResults.isClosed()) {
+
+			// The JDBC ResultSet hasn't been explicitly closed. Perform some
+			// basic cleanup and mark it as closed.
+			if (!isClosed) {
+				closeCurrentStream();
+				isClosed = true;
+			}
+
 			throw newSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN, operation);
 		}
 	}

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
Tue Mar  4 22:03:22 2008
@@ -1613,8 +1613,15 @@
             return null;
 
         // ignore closed result sets.
-        if (lrs.isClosed)
-            return null;
+        try {
+        	//following will check if the JDBC ResultSet or the language
+        	//ResultSet is closed. If yes, then it will throw an exception.
+        	//So, the exception indicates that the ResultSet is closed and
+        	//hence we should ignore it. 
+        	lrs.checkIfClosed("");
+        } catch (SQLException ex) {
+            return null;        	
+        }
         
         lrs.setDynamicResultSet(callStatement);
 

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
Tue Mar  4 22:03:22 2008
@@ -2693,7 +2693,11 @@
 
 	/**
 		If we are called as part of rollback code path, then we will reset all 
-		the activations. 
+		the activations that have resultset returning rows associated with 
+		them. DERBY-3304 Resultsets that do not return rows should be left 
+		alone when the rollback is through the JDBC Connection object. If the 
+		rollback is caused by an exception, then at that time, all kinds of
+		resultsets should be closed. 
 		
 		If we are called as part of commit code path, then we will do one of 
 		the following if the activation has resultset assoicated with it. Also,
@@ -2732,11 +2736,26 @@
 				continue;
 			}
 
+			//Determine if the activation has a resultset and if that resultset
+			//returns rows. For such an activation, we need to take special
+			//actions during commit and rollback as explained in the comments
+			//below.
+			ResultSet activationResultSet = a.getResultSet();
+			boolean resultsetReturnsRows =  
+				(activationResultSet != null) && activationResultSet.returnsRows(); ;
+
 			if (forRollback) { 
-				//Since we are dealing with rollback, we need to reset the 
-				//activation no matter what the holdability might be or no
-				//matter whether the associated resultset returns rows or not.
-				a.reset();
+				if (resultsetReturnsRows)
+					//Since we are dealing with rollback, we need to reset 
+					//the activation no matter what the holdability might 
+					//be provided that resultset returns rows. An example
+					//where we do not want to close a resultset that does
+					//not return rows would be a java procedure which has
+					//user invoked rollback inside of it. That rollback
+					//should not reset the activation associated with
+					//the call to java procedure because that activation
+					//is still being used.
+					a.reset();
 				// Only invalidate statements if we performed DDL.
 				if (dataDictionaryInWriteMode()) {
 					ExecPreparedStatement ps = a.getPreparedStatement();
@@ -2746,28 +2765,22 @@
 				}
 			} else {
 				//We are dealing with commit here. 
-				if (a.getResultSet() != null) {
-					ResultSet activationResultSet = a.getResultSet();
-					boolean resultsetReturnsRows = activationResultSet.returnsRows();
-					//if the activation has resultset associated with it, then 
-					//use following criteria to take the action
-					if (resultsetReturnsRows){
-						if (a.getResultSetHoldability() == false)
-							//Close result sets that return rows and are not held 
-							//across commit. This is to implement closing JDBC 
-							//result sets that are CLOSE_CURSOR_ON_COMMIT at commit 
-							//time. 
-							activationResultSet.close();
-						else 
-							//Clear the current row of the result sets that return
-							//rows and are held across commit. This is to implement
-							//keeping JDBC result sets open that are 
-							//HOLD_CURSORS_OVER_COMMIT at commit time and marking
-							//the resultset to be not on a valid row position. The 
-							//user will need to reposition within the resultset 
-							//before doing any row operations.
-							activationResultSet.clearCurrentRow();							
-					}
+				if (resultsetReturnsRows){
+					if (a.getResultSetHoldability() == false)
+						//Close result sets that return rows and are not held 
+						//across commit. This is to implement closing JDBC 
+						//result sets that are CLOSE_CURSOR_ON_COMMIT at commit 
+						//time. 
+						activationResultSet.close();
+					else 
+						//Clear the current row of the result sets that return
+						//rows and are held across commit. This is to implement
+						//keeping JDBC result sets open that are 
+						//HOLD_CURSORS_OVER_COMMIT at commit time and marking
+						//the resultset to be not on a valid row position. The 
+						//user will need to reposition within the resultset 
+						//before doing any row operations.
+						activationResultSet.clearCurrentRow();							
 				}
 				a.clearHeapConglomerateController();
 			}

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out
Tue Mar  4 22:03:22 2008
@@ -8,7 +8,7 @@
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
-ERROR 08003: No current connection.
+ERROR XCL16: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is
OFF.
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
 Test database shutdown ...

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out
Tue Mar  4 22:03:22 2008
@@ -8,7 +8,7 @@
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
-ERROR 08003: No current connection.
+ERROR XCL16: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is
OFF.
 ERROR 08003: No current connection.
 ERROR 08003: No current connection.
 Test database shutdown ...

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out
Tue Mar  4 22:03:22 2008
@@ -69,8 +69,7 @@
 values doConnCommitInt();
 1          
 -----------
-1          
-ERROR XCL16: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is
OFF.
+ERROR XCL16: ResultSet not open. Operation 'getString' not permitted. Verify that autocommit
is OFF.
 ij> -- values doConnStmtInt('commit');
 -- values doConnStmtInt('rollback');
 -- values doConnStmtInt('call doConnStmt(''call doConnStmt(''''commit'''')'')');

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
Tue Mar  4 22:03:22 2008
@@ -1445,6 +1445,21 @@
         rs1.close();
     }
 
+    /**
+     * Test that a {@code ResultSet} is marked as closed after commit if its
+     * holdability is {@code CLOSE_CURSORS_AT_COMMIT} (DERBY-3404).
+     */
+    public void testIsClosedOnNonHoldableResultSet() throws SQLException {
+        getConnection().setAutoCommit(false);
+        getConnection().setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+        ResultSet rs = createStatement().executeQuery(
+            "SELECT TABLENAME FROM SYS.SYSTABLES");
+        assertEquals("ResultSet shouldn't be holdable",
+                     ResultSet.CLOSE_CURSORS_AT_COMMIT, rs.getHoldability());
+        commit();
+        assertTrue("Commit should have closed the ResultSet", rs.isClosed());
+    }
+
     /************************************************************************
      **                        T E S T  S E T U P                           *
      ************************************************************************/

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java
Tue Mar  4 22:03:22 2008
@@ -2517,10 +2517,7 @@
             rsh.next();
             fail("rsh's connection not active id ");
         } catch (SQLException sqle) {
-            if (usingEmbedded())
-                assertSQLState("08003", sqle);
-            else if (usingDerbyNetClient())
-                assertSQLState("XCL16", sqle);
+            assertSQLState("XCL16", sqle);
         }
 
         // resume XA transaction and keep using rs");

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java?rev=633778&r1=633777&r2=633778&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java
Tue Mar  4 22:03:22 2008
@@ -797,10 +797,33 @@
             .execute("create procedure procWithRollback(p1 int) parameter style JAVA READS
SQL DATA dynamic result sets 1 language java external name 'org.apache.derbyTesting.functionTests.tests.lang.LangProcedureTest.rollbackInsideProc'");
             drs1 = prepareCall("CALL procWithRollback(3)");
             drs1.execute();
-            rs = drs1.getResultSet();
-
+            //Following shows that the rollback inside the java procedure will
+            //cuase procedure to return no resultset (A procedure does
+            //not return closed resultsets). In 10.2 codeline though, java
+            //procedure returns a closed resultset if there is a rollback 
+            //inside the java procedure.
+            JDBC.assertNoMoreResults(drs1);
             JDBC.assertClosed(rs1);
             JDBC.assertClosed(resultSet);
+
+            //Following shows that the rollback inside the java procedure will 
+            //only close the resultset created before the rollback. The 
+            //resultset created after the rollback will remain open and if it
+            //is a resultset returned through the procedure then it will be
+            //available to the caller of the procedure. Notice that even though
+            //the procedure is defined to 2 return dynamic resultsets, only one
+            //is returned because the other one was closed as a result of 
+            //rollback.
+            s.execute("create procedure procWithRollbackAnd2Resulsets"+
+            		"(p1 int) parameter style JAVA READS SQL DATA dynamic "+
+            		"result sets 2 language java external name "+
+            		"'org.apache.derbyTesting.functionTests.tests.lang.LangProcedureTest.rollbackInsideProcWith2ResultSets'");
+            drs1 = prepareCall("CALL procWithRollbackAnd2Resulsets(3)");
+            drs1.execute();
+            rs = drs1.getResultSet();
+            JDBC.assertDrainResults(rs);
+            JDBC.assertNoMoreResults(drs1);
+
             //Create a procedure which does an insert into a table. Then call 
             //it with parameters such that insert will fail because of 
             //duplicate key. The procedure also has couple select statements
@@ -823,7 +846,7 @@
             s.execute("DROP TABLE DELLATER1");
             s.execute("DROP TABLE DELLATER2");
             s.execute("DROP TABLE DELLATER3");
-
+            
             conn.setAutoCommit(oldAutoCommit);
         }
 
@@ -1150,6 +1173,35 @@
         ps.setInt(1, p1);
         data[0] = ps.executeQuery();
         conn.rollback();
+        conn.close();
+    }
+
+    /**
+     * A test case for DERBY-3304. An explicit rollback inside the procedure
+     * should close all the resultsets created before the call to the
+     * procedure and any resultsets created inside the procedure including
+     * the dynamic resultsets. But the resultset created after the rollback
+     * should stay open
+     * 
+     * @param p1
+     * @param data
+     * @throws SQLException
+     */
+    public static void rollbackInsideProcWith2ResultSets(int p1, 
+    		ResultSet[] data1,
+            ResultSet[] data2) 
+    throws SQLException {
+        Connection conn = DriverManager.getConnection(
+        		"jdbc:default:connection");
+        PreparedStatement ps = conn.prepareStatement(
+        		"select * from t1 where i = ?");
+        ps.setInt(1, p1);
+        data1[0] = ps.executeQuery();
+        conn.rollback();
+        ps = conn.prepareStatement(
+        		"select * from dellater1 where i = ?");
+        ps.setInt(1, p1);
+        data2[0] = ps.executeQuery();
         conn.close();
     }
 



Mime
View raw message