Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2EA49DC4E for ; Wed, 12 Sep 2012 15:11:01 +0000 (UTC) Received: (qmail 40155 invoked by uid 500); 12 Sep 2012 15:11:00 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 39345 invoked by uid 500); 12 Sep 2012 15:10:59 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 39270 invoked by uid 99); 12 Sep 2012 15:10:59 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Sep 2012 15:10:59 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Sep 2012 15:10:17 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BB67D23888FE; Wed, 12 Sep 2012 15:09:33 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1383996 - in /db/derby/code/branches/10.7: ./ java/client/org/apache/derby/client/am/LogicalConnection.java Date: Wed, 12 Sep 2012 15:09:33 -0000 To: derby-commits@db.apache.org From: kristwaa@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120912150933.BB67D23888FE@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kristwaa Date: Wed Sep 12 15:09:33 2012 New Revision: 1383996 URL: http://svn.apache.org/viewvc?rev=1383996&view=rev Log: DERBY-5561: Race conditions in LogicalConnection checking for a null physical connection Merged fix from trunk (revisions 1333305 and 1344183). I manually removed the part of the fix that was specific to JDBC 4.1, as this code doesn't exist in versions prior to 10.8 (getSchema and setSchema). Modified: db/derby/code/branches/10.7/ (props changed) db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/LogicalConnection.java Propchange: db/derby/code/branches/10.7/ ------------------------------------------------------------------------------ Merged /db/derby/code/trunk:r1333305,1334919 Modified: db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/LogicalConnection.java URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/LogicalConnection.java?rev=1383996&r1=1383995&r2=1383996&view=diff ============================================================================== --- db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/LogicalConnection.java (original) +++ db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/LogicalConnection.java Wed Sep 12 15:09:33 2012 @@ -24,17 +24,26 @@ import org.apache.derby.shared.common.re import java.sql.SQLException; - -// A simple delegation wrapper handle for a physical connection. -// All methods are forwarded to the underlying physical connection except for close() and isClosed(). -// When a physical connection is wrapped, it is non-null, when the logical connection -// is closed, the wrapped physical connection is always set to null. -// Both the finalizer and close() methods will always set the physical connection to null. -// After the physical conneciton is set to null, -// only the Pooled Connection instance will maintain a handle to the physical connection. - +/** + * A simple delegation wrapper handle for a physical connection. + *

+ * All methods of the {@code Connection} interface are forwarded to the + * underlying physical connection, except for {@link #close()} and + * {@link #isClosed()}. When a physical connection is wrapped, it is non-null, + * when the logical connection is closed, the wrapped physical connection is + * always set to {@code null}. + * Both the finalizer and the {@code close}-methods will always set the + * physical connection to {@code null}. After the physical connection has been + * nulled out, only the {@code PooledConnection} instance will maintain a + * handle to the physical connection. + */ public class LogicalConnection implements java.sql.Connection { - protected Connection physicalConnection_ = null; // reset to null when the logical connection is closed. + /** + * Underlying physical connection for this logical connection. + *

+ * Set to {@code null} when this logical connection is closed. + */ + Connection physicalConnection_; private org.apache.derby.client.ClientPooledConnection pooledConnection_ = null; /** * Logical database metadata object created on demand and then cached. @@ -129,10 +138,17 @@ public class LogicalConnection implement // --------------------------- helper methods -------------------------------- - // this method doesn't wrap in the standard way, because it went out without a throws clause. - // Unlike all other LogicalConnection methods, if the physical connection is null, it won't throw an exception, but will return false. - - protected void checkForNullPhysicalConnection() throws SQLException { + /** + * Verifies that there is an underlying physical connection for this + * logical connection. + *

+ * If the physical connection has been nulled out it means that this + * logical connection has been closed. + * + * @throws SQLException if this logical connection has been closed + */ + protected final void checkForNullPhysicalConnection() + throws SQLException { if (physicalConnection_ == null) { SqlException se = new SqlException(null, new ClientMessageId(SQLState.NO_CURRENT_CONNECTION)); @@ -141,14 +157,14 @@ public class LogicalConnection implement } /** - * This method checks if the physcial connection underneath is null and - * if yes, then it simply returns. - * Otherwise, if the severity of exception is greater than equal to - * ExceptionSeverity.SESSION_SEVERITY, then we will send - * connectionErrorOccurred event to all the registered listeners. + * Notifies listeners about exceptions of session level severity or higher. + *

+ * The exception, even if the severity is sufficiently high, is ignored if + * the underlying physical connection has been nulled out. Otherwise a + * {@code connectionErrorOccurred}-event is sent to all the registered + * listeners. * - * @param sqle SQLException An event will be sent to the listeners if the - * exception's severity is >= ExceptionSeverity.SESSION_SEVERITY. + * @param sqle the cause of the notification */ final void notifyException(SQLException sqle) { if (physicalConnection_ != null) @@ -197,7 +213,7 @@ public class LogicalConnection implement } } - public String nativeSQL(String sql) throws SQLException { + synchronized public String nativeSQL(String sql) throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.nativeSQL(sql); @@ -217,7 +233,7 @@ public class LogicalConnection implement } } - public boolean getAutoCommit() throws SQLException { + synchronized public boolean getAutoCommit() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getAutoCommit(); @@ -257,7 +273,7 @@ public class LogicalConnection implement } } - public int getTransactionIsolation() throws SQLException { + synchronized public int getTransactionIsolation() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getTransactionIsolation(); @@ -267,7 +283,7 @@ public class LogicalConnection implement } } - public java.sql.SQLWarning getWarnings() throws SQLException { + synchronized public java.sql.SQLWarning getWarnings() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getWarnings(); @@ -363,7 +379,7 @@ public class LogicalConnection implement } } - public boolean isReadOnly() throws SQLException { + synchronized public boolean isReadOnly() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.isReadOnly(); @@ -383,7 +399,7 @@ public class LogicalConnection implement } } - public String getCatalog() throws SQLException { + synchronized public String getCatalog() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getCatalog(); @@ -428,7 +444,7 @@ public class LogicalConnection implement } } - public java.util.Map getTypeMap() throws SQLException { + synchronized public java.util.Map getTypeMap() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getTypeMap(); @@ -448,7 +464,7 @@ public class LogicalConnection implement } } - public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency, + synchronized public java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { try { checkForNullPhysicalConnection(); @@ -459,7 +475,7 @@ public class LogicalConnection implement } } - public java.sql.CallableStatement prepareCall(String sql, int resultSetType, + synchronized public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { try { @@ -471,7 +487,7 @@ public class LogicalConnection implement } } - public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, + synchronized public java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { try { @@ -484,7 +500,7 @@ public class LogicalConnection implement } } - public java.sql.PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) + synchronized public java.sql.PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { try { checkForNullPhysicalConnection(); @@ -495,7 +511,7 @@ public class LogicalConnection implement } } - public java.sql.PreparedStatement prepareStatement(String sql, int columnIndexes[]) + synchronized public java.sql.PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException { try { checkForNullPhysicalConnection(); @@ -506,7 +522,7 @@ public class LogicalConnection implement } } - public java.sql.PreparedStatement prepareStatement(String sql, String columnNames[]) + synchronized public java.sql.PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException { try { checkForNullPhysicalConnection(); @@ -517,7 +533,7 @@ public class LogicalConnection implement } } - public void setHoldability(int holdability) throws SQLException { + synchronized public void setHoldability(int holdability) throws SQLException { try { checkForNullPhysicalConnection(); physicalConnection_.setHoldability(holdability); @@ -527,7 +543,7 @@ public class LogicalConnection implement } } - public int getHoldability() throws SQLException { + synchronized public int getHoldability() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.getHoldability(); @@ -537,7 +553,7 @@ public class LogicalConnection implement } } - public java.sql.Savepoint setSavepoint() throws SQLException { + synchronized public java.sql.Savepoint setSavepoint() throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.setSavepoint(); @@ -547,7 +563,7 @@ public class LogicalConnection implement } } - public java.sql.Savepoint setSavepoint(String name) throws SQLException { + synchronized public java.sql.Savepoint setSavepoint(String name) throws SQLException { try { checkForNullPhysicalConnection(); return physicalConnection_.setSavepoint(name); @@ -557,7 +573,7 @@ public class LogicalConnection implement } } - public void rollback(java.sql.Savepoint savepoint) throws SQLException { + synchronized public void rollback(java.sql.Savepoint savepoint) throws SQLException { try { checkForNullPhysicalConnection(); physicalConnection_.rollback(savepoint); @@ -567,7 +583,7 @@ public class LogicalConnection implement } } - public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException { + synchronized public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException { try { checkForNullPhysicalConnection(); physicalConnection_.releaseSavepoint(savepoint);