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 ma...@apache.org on 2009/08/31 23:29:58 UTC
svn commit: r809750 - in /db/derby/code/branches/10.3: ./
java/drda/org/apache/derby/impl/drda/ java/engine/org/apache/derby/iapi/jdbc/
java/engine/org/apache/derby/impl/jdbc/ java/engine/org/apache/derby/jdbc/
java/testing/org/apache/derbyTesting/func...
Author: mamta
Date: Mon Aug 31 21:29:57 2009
New Revision: 809750
URL: http://svn.apache.org/viewvc?rev=809750&view=rev
Log:
DERBY-4053
Merging DERBY-4053 into 10.3 codeline. Additionally merging partial DERBY-3319 and partial DERBY-2855 because of the code dependency of DERBY-4053 changes
Modified:
db/derby/code/branches/10.3/ (props changed)
db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/Database.java
db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/XADatabase.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java
db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
Propchange: db/derby/code/branches/10.3/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug 31 21:29:57 2009
@@ -1 +1 @@
-/db/derby/code/trunk:552046,788436
+/db/derby/code/trunk:552046,788436,793588
Modified: db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/Database.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/Database.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/Database.java (original)
+++ db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/Database.java Mon Aug 31 21:29:57 2009
@@ -70,7 +70,6 @@
protected boolean RDBUPDRM_sent = false; //We have sent that an update
// occurred in this transaction
protected boolean sendTRGDFTRT = false; // Send package target default value
-
/**
* Connection to the database in the embedded engine.
*/
@@ -80,8 +79,6 @@
private DRDAStatement currentStatement; // current statement we are working on
private Hashtable stmtTable; // Hash table for storing statements
- boolean forXA = false;
-
// constructor
/**
* Database constructor
@@ -332,7 +329,12 @@
conn.rollback();
}
/**
- * Close the connection and clean up the statement table
+ * Database close does following cleanup tasks
+ * 1)Rollback any pending transaction on the Connection object (except
+ * for a global-XA Connection obejct) before closing the Connection.
+ * Without the rollback, the Connection close will result into an
+ * exception if there is a pending transaction on that Connection.
+ * 2)Clean up the statement table
* @throws SQLException on conn.close() error to be handled in DRDAConnThread.
*/
protected void close() throws SQLException
@@ -351,7 +353,8 @@
defaultStatement.close();
if ((conn != null) && !conn.isClosed())
{
- if (! forXA)
+ //rollback all the pending transactions except global XA trans
+ if (! conn.isInGlobalTransaction())
{
conn.rollback();
}
Modified: db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/XADatabase.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/XADatabase.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/XADatabase.java (original)
+++ db/derby/code/branches/10.3/java/drda/org/apache/derby/impl/drda/XADatabase.java Mon Aug 31 21:29:57 2009
@@ -56,7 +56,6 @@
XADatabase (String dbName)
{
super(dbName);
- forXA = true;
}
/**
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java Mon Aug 31 21:29:57 2009
@@ -473,6 +473,11 @@
}
}
+ /** @see EngineConnection#isInGlobalTransaction() */
+ public boolean isInGlobalTransaction() {
+ return control.isInGlobalTransaction();
+ }
+
/**
* Set the internal isolation level to use for preparing statements.
* Subsequent prepares will use this isoalation level
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java Mon Aug 31 21:29:57 2009
@@ -83,6 +83,12 @@
*/
public void resetIsolationLevelFlag() throws SQLException;
+ /**
+ * Is this a global transaction
+ * @return true if this is a global XA transaction
+ */
+ public boolean isInGlobalTransaction();
+
/**
Close called on BrokeredConnection. If this call
returns true then getRealConnection().close() will be called.
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/jdbc/EngineConnection.java Mon Aug 31 21:29:57 2009
@@ -40,6 +40,12 @@
*/
public void setDrdaID(String drdaID);
+ /**
+ * Is this a global transaction
+ * @return true if this is a global XA transaction
+ */
+ public boolean isInGlobalTransaction();
+
/**
* Set the transaction isolation level that will be used for the
* next prepare. Used by network server to implement DB2 style
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Mon Aug 31 21:29:57 2009
@@ -2036,6 +2036,11 @@
getLanguageConnection().setDrdaID(drdaID);
}
+ /** @see EngineConnection#isInGlobalTransaction() */
+ public boolean isInGlobalTransaction() {
+ return false;
+ }
+
/**
Reset the connection before it is returned from a PooledConnection
to a new application request (wrapped by a BrokeredConnection).
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java Mon Aug 31 21:29:57 2009
@@ -369,7 +369,11 @@
public void resetIsolationLevelFlag() throws SQLException {
realConnection.getLanguageConnection().resetIsolationLevelFlagUsedForSQLandJDBC();
}
-
+
+ /** @see BrokeredConnectionControl#isInGlobalTransaction() */
+ public boolean isInGlobalTransaction() {
+ return false;
+ }
/**
Notify the control class that a SQLException was thrown
Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/jdbc/EmbedXAConnection.java Mon Aug 31 21:29:57 2009
@@ -22,6 +22,7 @@
package org.apache.derby.jdbc;
import org.apache.derby.impl.jdbc.Util;
+import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;
import org.apache.derby.iapi.jdbc.EngineConnection;
import org.apache.derby.iapi.jdbc.ResourceAdapter;
@@ -53,6 +54,21 @@
xaRes = new EmbedXAResource (this, ra);
}
+ /** @see BrokeredConnectionControl#isInGlobalTransaction() */
+ public boolean isInGlobalTransaction() {
+ return isGlobal();
+ }
+
+ /**
+ * Check if this connection is part of a global XA transaction.
+ *
+ * @return {@code true} if the transaction is global, {@code false} if the
+ * transaction is local
+ */
+ private boolean isGlobal() {
+ return xaRes.getCurrentXid () != null;
+ }
+
/*
** XAConnection methods
*/
Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/XATransactionTest.java Mon Aug 31 21:29:57 2009
@@ -48,6 +48,55 @@
*/
public class XATransactionTest extends BaseJDBCTestCase {
+ /**
+ * This test does following
+ * 1)Start the network server
+ * 2)Start a local xa transaction
+ * 3)Do not commit the local XA transaction
+ * 4)Shutdown the network server
+ * 5)Start the server again
+ *
+ * Before the fix for DERBY-4053 went in, step 4) would not shutdown the
+ * server properly because of the pending local XA transaction. During the
+ * server shutdown, we try to close all the open connections but the close
+ * on the XA connection results into an exception because there is still a
+ * pending transaction. That exception is not handled by the server and
+ * because of that, all the code necessary to shutdown the server is not
+ * executed. The next time around, step 5), when we try to bring up the
+ * server again, it ends up hanging
+ * 2009-07-09 21:21:28.828 GMT : Invalid reply from network server: Insufficient data.
+ * 2009-07-09 21:21:28.843 GMT : Could not listen on port 1527 on host 127.0.0.1: java.net.BindException: Address already in use: JVM_Bind
+ *
+ * The fix for DERBY-4053 makes sure that before calling close on local XA
+ * transaction, we first rollback any transaction active on the
+ * connection.
+ */
+ public void testPendingLocalTranAndServerShutdown() throws Exception {
+ if (usingEmbedded())
+ return;
+ //1)Server must be up already through the Derby junit framework
+ //2)Start a local xa transaction
+ XADataSource xaDataSource = J2EEDataSource.getXADataSource();
+ XAConnection xaconn = xaDataSource.getXAConnection();
+ XAResource xar = xaconn.getXAResource();
+ Connection conn = xaconn.getConnection();
+ Statement s = conn.createStatement();
+ s.executeUpdate("create table tab(i int)");
+ s.executeUpdate("insert into tab values (1),(2),(3),(4)");
+ conn.commit();
+ conn.setAutoCommit(false);
+ ResultSet rs = s.executeQuery("select * from tab");
+ rs.next();
+ //3)Do not commit this pending local XA transaction
+
+ //4)Shutdown the network server
+ //bring the server down while the local xa transaction is still active
+ TestConfiguration.getCurrent().stopNetworkServer();
+
+ //5)Start the server again
+ TestConfiguration.getCurrent().startNetworkServer();
+ }
+
public void testGlobalXIDinTransactionTable() throws Exception {
Statement stm = getConnection().createStatement();
stm.execute("create table XATT2 (i int, text char(10))");
Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java?rev=809750&r1=809749&r2=809750&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java Mon Aug 31 21:29:57 2009
@@ -20,6 +20,10 @@
package org.apache.derbyTesting.junit;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.net.InetAddress;
import java.security.*;
import java.sql.Connection;
import java.sql.SQLException;
@@ -27,6 +31,8 @@
import java.util.ArrayList;
import java.util.Hashtable;
+import org.apache.derby.drda.NetworkServerControl;
+
import junit.extensions.TestSetup;
import junit.framework.Assert;
import junit.framework.Test;
@@ -68,7 +74,16 @@
public final static String DEFAULT_SSL = "off";
public final static String TEST_DBO = "TEST_DBO";
-
+
+ private FileOutputStream serverOutput;
+
+ /** Sleep for 500 ms before pinging the network server (again) */
+ private static final int SLEEP_TIME = 1000;
+
+ /* Network Server Control */
+ private NetworkServerControl networkServerController;
+ private NetworkServerControl networkServer;
+
/**
* Keys to use to look up values in properties files.
*/
@@ -1113,7 +1128,84 @@
BaseJDBCTestCase.assertSQLState("Engine shutdown", "XJ015", e);
}
}
+
/**
+ * stops the Network server for this configuration.
+ *
+ */
+ public void stopNetworkServer() {
+ try {
+ NetworkServerControl networkServer = new NetworkServerControl();
+ networkServer.shutdown();
+ if (serverOutput != null) {
+ serverOutput.close();
+ }
+ } catch(Exception e) {
+ SQLException se = new SQLException("Error shutting down server");
+ se.initCause(e);
+ }
+ }
+
+ /**
+ * starts the Networs server for this configuration.
+ *
+ */
+ public void startNetworkServer() throws SQLException
+ {
+ Exception failException = null;
+ try {
+
+ NetworkServerControl networkServer =
+ new NetworkServerControl(InetAddress.getByName("localhost"), port);
+ serverOutput = (FileOutputStream)
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ File logs = new File("logs");
+ logs.mkdir();
+ File console = new File(logs, "serverConsoleOutput.log");
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(console.getPath(), true);
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ }
+ return fos;
+ }
+ });
+
+ networkServer.start(new PrintWriter(serverOutput));
+
+ // Wait for the network server to start
+ boolean started = false;
+ int retries = 10; // Max retries = max seconds to wait
+
+ while (!started && retries > 0) {
+ try {
+ // Sleep 1 second and then ping the network server
+ Thread.sleep(SLEEP_TIME);
+ networkServer.ping();
+
+ // If ping does not throw an exception the server has started
+ started = true;
+ } catch(Exception e) {
+ retries--;
+ failException = e;
+ }
+
+ }
+
+ // Check if we got a reply on ping
+ if (!started) {
+ throw failException;
+ }
+ } catch (Exception e) {
+ SQLException se = new SQLException("Error starting network server");
+ se.initCause(failException);
+ throw se;
+ }
+ }
+
+ /**
* Set the verbosity, i.e., whether debug statements print.
*/
public void setVerbosity( boolean isChatty ) { isVerbose = isChatty; }