Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java 
Tue Jan 29 15:03:15 2019
@@ -46,6 +46,53 @@ public class PoolableConnectionFactory i
     private static final Log log = 
LogFactory.getLog(PoolableConnectionFactory.class);
 
     /**
+     * Internal constant to indicate the level is not set.
+     */
+    static final int UNKNOWN_TRANSACTION_ISOLATION = -1;
+
+    private final ConnectionFactory connectionFactory;
+
+    private final ObjectName dataSourceJmxObjectName;
+
+    private volatile String validationQuery;
+
+    private volatile int validationQueryTimeoutSeconds = -1;
+
+    private Collection<String> connectionInitSqls;
+
+    private Collection<String> disconnectionSqlCodes;
+
+    private boolean fastFailValidation = true;
+
+    private volatile ObjectPool<PoolableConnection> pool;
+
+    private Boolean defaultReadOnly;
+
+    private Boolean defaultAutoCommit;
+
+    private boolean autoCommitOnReturn = true;
+
+    private boolean rollbackOnReturn = true;
+
+    private int defaultTransactionIsolation = UNKNOWN_TRANSACTION_ISOLATION;
+
+    private String defaultCatalog;
+
+    private String defaultSchema;
+
+    private boolean cacheState;
+
+    private boolean poolStatements;
+
+    private int maxOpenPreparedStatements = 
GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL_PER_KEY;
+
+    private long maxConnLifetimeMillis = -1;
+
+    private final AtomicLong connectionIndex = new AtomicLong(0);
+
+    private Integer defaultQueryTimeoutSeconds;
+
+    /**
      * Creates a new {@code PoolableConnectionFactory}.
      *
      * @param connFactory
@@ -58,179 +105,135 @@ public class PoolableConnectionFactory i
         this.dataSourceJmxObjectName = dataSourceJmxObjectName;
     }
 
-    /**
-     * Sets the query I use to {@link #validateObject validate} {@link 
Connection}s. Should return at least one row. If
-     * not specified, {@link Connection#isValid(int)} will be used to validate 
connections.
-     *
-     * @param validationQuery
-     *            a query to use to {@link #validateObject validate} {@link 
Connection}s.
-     */
-    public void setValidationQuery(final String validationQuery) {
-        this.validationQuery = validationQuery;
+    @Override
+    public void activateObject(final PooledObject<PoolableConnection> p) 
throws Exception {
+
+        validateLifetime(p);
+
+        final PoolableConnection conn = p.getObject();
+        conn.activate();
+
+        if (defaultAutoCommit != null && conn.getAutoCommit() != 
defaultAutoCommit.booleanValue()) {
+            conn.setAutoCommit(defaultAutoCommit.booleanValue());
+        }
+        if (defaultTransactionIsolation != UNKNOWN_TRANSACTION_ISOLATION
+                && conn.getTransactionIsolation() != 
defaultTransactionIsolation) {
+            conn.setTransactionIsolation(defaultTransactionIsolation);
+        }
+        if (defaultReadOnly != null && conn.isReadOnly() != 
defaultReadOnly.booleanValue()) {
+            conn.setReadOnly(defaultReadOnly.booleanValue());
+        }
+        if (defaultCatalog != null && 
!defaultCatalog.equals(conn.getCatalog())) {
+            conn.setCatalog(defaultCatalog);
+        }
+        if (defaultSchema != null && 
!defaultSchema.equals(Jdbc41Bridge.getSchema(conn))) {
+            Jdbc41Bridge.setSchema(conn, defaultSchema);
+        }
+        conn.setDefaultQueryTimeout(defaultQueryTimeoutSeconds);
     }
 
-    /**
-     * Sets the validation query timeout, the amount of time, in seconds, that 
connection validation will wait for a
-     * response from the database when executing a validation query. Use a 
value less than or equal to 0 for no timeout.
-     *
-     * @param validationQueryTimeoutSeconds
-     *            new validation query timeout value in seconds
-     */
-    public void setValidationQueryTimeout(final int 
validationQueryTimeoutSeconds) {
-        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
+    @Override
+    public void destroyObject(final PooledObject<PoolableConnection> p) throws 
Exception {
+        p.getObject().reallyClose();
     }
 
     /**
-     * Sets the SQL statements I use to initialize newly created {@link 
Connection}s. Using {@code null} turns off
-     * connection initialization.
-     *
-     * @param connectionInitSqls
-     *            SQL statement to initialize {@link Connection}s.
+     * @return The cache state.
+     * @since Made public in 2.6.0.
      */
-    public void setConnectionInitSql(final Collection<String> 
connectionInitSqls) {
-        this.connectionInitSqls = connectionInitSqls;
+    public boolean getCacheState() {
+        return cacheState;
     }
 
     /**
-     * Sets the {@link ObjectPool} in which to pool {@link Connection}s.
-     *
-     * @param pool
-     *            the {@link ObjectPool} in which to pool those {@link 
Connection}s
+     * @return The connection factory.
+     * @since Made public in 2.6.0.
      */
-    public synchronized void setPool(final ObjectPool<PoolableConnection> 
pool) {
-        if (null != this.pool && pool != this.pool) {
-            try {
-                this.pool.close();
-            } catch (final Exception e) {
-                // ignored !?!
-            }
-        }
-        this.pool = pool;
+    public ConnectionFactory getConnectionFactory() {
+        return connectionFactory;
     }
 
-    /**
-     * Returns the {@link ObjectPool} in which {@link Connection}s are pooled.
-     *
-     * @return the connection pool
-     */
-    public synchronized ObjectPool<PoolableConnection> getPool() {
-        return pool;
+    protected AtomicLong getConnectionIndex() {
+        return connectionIndex;
     }
 
     /**
-     * Sets the default "read only" setting for borrowed {@link Connection}s
-     *
-     * @param defaultReadOnly
-     *            the default "read only" setting for borrowed {@link 
Connection}s
+     * @return The collection of initialization SQL statements.
+     * @since 2.6.0
      */
-    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
-        this.defaultReadOnly = defaultReadOnly;
+    public Collection<String> getConnectionInitSqls() {
+        return connectionInitSqls;
     }
 
     /**
-     * Sets the default "auto commit" setting for borrowed {@link Connection}s
-     *
-     * @param defaultAutoCommit
-     *            the default "auto commit" setting for borrowed {@link 
Connection}s
+     * @return The data source JMX ObjectName
+     * @since Made public in 2.6.0.
      */
-    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
-        this.defaultAutoCommit = defaultAutoCommit;
+    public ObjectName getDataSourceJmxName() {
+        return dataSourceJmxObjectName;
     }
 
     /**
-     * Sets the default "Transaction Isolation" setting for borrowed {@link 
Connection}s
-     *
-     * @param defaultTransactionIsolation
-     *            the default "Transaction Isolation" setting for returned 
{@link Connection}s
+     * @return The data source JMS ObjectName.
+     * @since 2.6.0
      */
-    public void setDefaultTransactionIsolation(final int 
defaultTransactionIsolation) {
-        this.defaultTransactionIsolation = defaultTransactionIsolation;
+    public ObjectName getDataSourceJmxObjectName() {
+        return dataSourceJmxObjectName;
     }
 
     /**
-     * Sets the default "catalog" setting for borrowed {@link Connection}s
-     *
-     * @param defaultCatalog
-     *            the default "catalog" setting for borrowed {@link 
Connection}s
+     * @return Default auto-commit value.
+     * @since 2.6.0
      */
-    public void setDefaultCatalog(final String defaultCatalog) {
-        this.defaultCatalog = defaultCatalog;
+    public Boolean getDefaultAutoCommit() {
+        return defaultAutoCommit;
     }
 
     /**
-     * Sets the default "schema" setting for borrowed {@link Connection}s
-     *
-     * @param defaultSchema
-     *            the default "schema" setting for borrowed {@link Connection}s
-     * @since 2.5.0
+     * @return Default catalog.
+     * @since 2.6.0
      */
-    public void setDefaultSchema(final String defaultSchema) {
-        this.defaultSchema = defaultSchema;
-    }
-
-    public void setCacheState(final boolean cacheState) {
-        this.cacheState = cacheState;
-    }
-
-    public void setPoolStatements(final boolean poolStatements) {
-        this.poolStatements = poolStatements;
+    public String getDefaultCatalog() {
+        return defaultCatalog;
     }
 
     /**
-     * Deprecated due to typo in method name.
-     *
-     * @param maxOpenPreparedStatements
-     *            The maximum number of open prepared statements.
-     * @deprecated Use {@link #setMaxOpenPreparedStatements(int)}.
+     * @return Default query timeout in seconds.
      */
-    @Deprecated // Due to typo in method name.
-    public void setMaxOpenPrepatedStatements(final int 
maxOpenPreparedStatements) {
-        setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+    public Integer getDefaultQueryTimeout() {
+        return defaultQueryTimeoutSeconds;
     }
 
     /**
-     * Sets the maximum number of open prepared statements.
-     *
-     * @param maxOpenPreparedStatements
-     *            The maximum number of open prepared statements.
+     * @return Default query timeout in seconds.
+     * @since 2.6.0
      */
-    public void setMaxOpenPreparedStatements(final int 
maxOpenPreparedStatements) {
-        this.maxOpenPreparedStatements = maxOpenPreparedStatements;
+    public Integer getDefaultQueryTimeoutSeconds() {
+        return defaultQueryTimeoutSeconds;
     }
 
     /**
-     * Sets the maximum lifetime in milliseconds of a connection after which 
the connection will always fail activation,
-     * passivation and validation. A value of zero or less indicates an 
infinite lifetime. The default value is -1.
-     *
-     * @param maxConnLifetimeMillis
-     *            The maximum lifetime in milliseconds.
+     * @return Default read-only-value.
+     * @since 2.6.0
      */
-    public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
-        this.maxConnLifetimeMillis = maxConnLifetimeMillis;
-    }
-
-    public boolean isEnableAutoCommitOnReturn() {
-        return enableAutoCommitOnReturn;
-    }
-
-    public void setEnableAutoCommitOnReturn(final boolean 
enableAutoCommitOnReturn) {
-        this.enableAutoCommitOnReturn = enableAutoCommitOnReturn;
-    }
-
-    public boolean isRollbackOnReturn() {
-        return rollbackOnReturn;
+    public Boolean getDefaultReadOnly() {
+        return defaultReadOnly;
     }
 
-    public void setRollbackOnReturn(final boolean rollbackOnReturn) {
-        this.rollbackOnReturn = rollbackOnReturn;
-    }
-
-    public Integer getDefaultQueryTimeout() {
-        return defaultQueryTimeoutSeconds;
+    /**
+     * @return Default schema.
+     * @since 2.6.0
+     */
+    public String getDefaultSchema() {
+        return defaultSchema;
     }
 
-    public void setDefaultQueryTimeout(final Integer 
defaultQueryTimeoutSeconds) {
-        this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
+    /**
+     * @return Default transaction isolation.
+     * @since 2.6.0
+     */
+    public int getDefaultTransactionIsolation() {
+        return defaultTransactionIsolation;
     }
 
     /**
@@ -254,51 +257,112 @@ public class PoolableConnectionFactory i
     }
 
     /**
-     * @param disconnectionSqlCodes
-     *            The disconnection SQL codes.
-     * @see #getDisconnectionSqlCodes()
-     * @since 2.1
+     * @return Maximum connection lifetime in milliseconds.
+     * @since 2.6.0
      */
-    public void setDisconnectionSqlCodes(final Collection<String> 
disconnectionSqlCodes) {
-        this.disconnectionSqlCodes = disconnectionSqlCodes;
+    public long getMaxConnLifetimeMillis() {
+        return maxConnLifetimeMillis;
+    }
+
+    protected int getMaxOpenPreparedStatements() {
+        return maxOpenPreparedStatements;
     }
 
     /**
-     * True means that validation will fail immediately for connections that 
have previously thrown SQLExceptions with
-     * SQL_STATE indicating fatal disconnection errors.
+     * Returns the {@link ObjectPool} in which {@link Connection}s are pooled.
      *
-     * @return true if connections created by this factory will fast fail 
validation.
-     * @see #setDisconnectionSqlCodes(Collection)
-     * @since 2.1
-     * @since 2.5.0 Defaults to true, previous versions defaulted to false.
+     * @return the connection pool
      */
-    public boolean isFastFailValidation() {
-        return fastFailValidation;
+    public synchronized ObjectPool<PoolableConnection> getPool() {
+        return pool;
     }
 
     /**
-     * @see #isFastFailValidation()
-     * @param fastFailValidation
-     *            true means connections created by this factory will fast 
fail validation
-     * @since 2.1
+     * @return Whether to pool statements.
+     * @since Made public in 2.6.0.
      */
-    public void setFastFailValidation(final boolean fastFailValidation) {
-        this.fastFailValidation = fastFailValidation;
+    public boolean getPoolStatements() {
+        return poolStatements;
     }
-
-    @Override
-    public PooledObject<PoolableConnection> makeObject() throws Exception {
-        Connection conn = connectionFactory.createConnection();
-        if (conn == null) {
-            throw new IllegalStateException("Connection factory returned null 
from createConnection");
+    /**
+     * @return Validation query.
+     * @since 2.6.0
+     */
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+    /**
+     * @return Validation query timeout in seconds.
+     * @since 2.6.0
+     */
+    public int getValidationQueryTimeoutSeconds() {
+        return validationQueryTimeoutSeconds;
+    }
+    protected void initializeConnection(final Connection conn) throws 
SQLException {
+        final Collection<String> sqls = connectionInitSqls;
+        if (conn.isClosed()) {
+            throw new SQLException("initializeConnection: connection closed");
         }
-        try {
-            initializeConnection(conn);
-        } catch (final SQLException sqle) {
-            // Make sure the connection is closed
-            try {
-                conn.close();
-            } catch (final SQLException ignore) {
+        if (null != sqls) {
+            try (Statement stmt = conn.createStatement()) {
+                for (final String sql : sqls) {
+                    Objects.requireNonNull(sql, "null connectionInitSqls 
element");
+                    stmt.execute(sql);
+                }
+            }
+        }
+    }
+
+    /**
+     * @return Whether to auto-commit on return.
+     * @since 2.6.0
+     */
+    public boolean isAutoCommitOnReturn() {
+        return autoCommitOnReturn;
+    }
+
+    /**
+     * @return Whether to auto-commit on return.
+     * @deprecated Use {@link #isAutoCommitOnReturn()}.
+     */
+    @Deprecated
+    public boolean isEnableAutoCommitOnReturn() {
+        return autoCommitOnReturn;
+    }
+
+    /**
+     * True means that validation will fail immediately for connections that 
have previously thrown SQLExceptions with
+     * SQL_STATE indicating fatal disconnection errors.
+     *
+     * @return true if connections created by this factory will fast fail 
validation.
+     * @see #setDisconnectionSqlCodes(Collection)
+     * @since 2.1
+     * @since 2.5.0 Defaults to true, previous versions defaulted to false.
+     */
+    public boolean isFastFailValidation() {
+        return fastFailValidation;
+    }
+
+    /**
+     * @return Whether to rollback on return.
+     */
+    public boolean isRollbackOnReturn() {
+        return rollbackOnReturn;
+    }
+
+    @Override
+    public PooledObject<PoolableConnection> makeObject() throws Exception {
+        Connection conn = connectionFactory.createConnection();
+        if (conn == null) {
+            throw new IllegalStateException("Connection factory returned null 
from createConnection");
+        }
+        try {
+            initializeConnection(conn);
+        } catch (final SQLException sqle) {
+            // Make sure the connection is closed
+            try {
+                conn.close();
+            } catch (final SQLException ignore) {
                 // ignore
             }
             // Rethrow original exception so it is visible to caller
@@ -347,48 +411,6 @@ public class PoolableConnectionFactory i
         return new DefaultPooledObject<>(pc);
     }
 
-    protected void initializeConnection(final Connection conn) throws 
SQLException {
-        final Collection<String> sqls = connectionInitSqls;
-        if (conn.isClosed()) {
-            throw new SQLException("initializeConnection: connection closed");
-        }
-        if (null != sqls) {
-            try (Statement stmt = conn.createStatement()) {
-                for (final String sql : sqls) {
-                    Objects.requireNonNull(sql, "null connectionInitSqls 
element");
-                    stmt.execute(sql);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void destroyObject(final PooledObject<PoolableConnection> p) throws 
Exception {
-        p.getObject().reallyClose();
-    }
-
-    @Override
-    public boolean validateObject(final PooledObject<PoolableConnection> p) {
-        try {
-            validateLifetime(p);
-
-            validateConnection(p.getObject());
-            return true;
-        } catch (final Exception e) {
-            if (log.isDebugEnabled()) {
-                
log.debug(Utils.getMessage("poolableConnectionFactory.validateObject.fail"), e);
-            }
-            return false;
-        }
-    }
-
-    public void validateConnection(final PoolableConnection conn) throws 
SQLException {
-        if (conn.isClosed()) {
-            throw new SQLException("validateConnection: connection closed");
-        }
-        conn.validate(validationQuery, validationQueryTimeoutSeconds);
-    }
-
     @Override
     public void passivateObject(final PooledObject<PoolableConnection> p) 
throws Exception {
 
@@ -407,7 +429,7 @@ public class PoolableConnectionFactory i
 
         // DBCP-97 / DBCP-399 / DBCP-351 Idle connections in the pool should
         // have autoCommit enabled
-        if (enableAutoCommitOnReturn) {
+        if (autoCommitOnReturn) {
             if (connAutoCommit == null) {
                 connAutoCommit = Boolean.valueOf(conn.getAutoCommit());
             }
@@ -419,91 +441,217 @@ public class PoolableConnectionFactory i
         conn.passivate();
     }
 
-    @Override
-    public void activateObject(final PooledObject<PoolableConnection> p) 
throws Exception {
+    public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
+        this.autoCommitOnReturn = autoCommitOnReturn;
+    }
 
-        validateLifetime(p);
+    public void setCacheState(final boolean cacheState) {
+        this.cacheState = cacheState;
+    }
 
-        final PoolableConnection conn = p.getObject();
-        conn.activate();
+    /**
+     * Sets the SQL statements I use to initialize newly created {@link 
Connection}s. Using {@code null} turns off
+     * connection initialization.
+     *
+     * @param connectionInitSqls
+     *            SQL statement to initialize {@link Connection}s.
+     */
+    public void setConnectionInitSql(final Collection<String> 
connectionInitSqls) {
+        this.connectionInitSqls = connectionInitSqls;
+    }
 
-        if (defaultAutoCommit != null && conn.getAutoCommit() != 
defaultAutoCommit.booleanValue()) {
-            conn.setAutoCommit(defaultAutoCommit.booleanValue());
-        }
-        if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION
-                && conn.getTransactionIsolation() != 
defaultTransactionIsolation) {
-            conn.setTransactionIsolation(defaultTransactionIsolation);
-        }
-        if (defaultReadOnly != null && conn.isReadOnly() != 
defaultReadOnly.booleanValue()) {
-            conn.setReadOnly(defaultReadOnly.booleanValue());
-        }
-        if (defaultCatalog != null && 
!defaultCatalog.equals(conn.getCatalog())) {
-            conn.setCatalog(defaultCatalog);
-        }
-        if (defaultSchema != null && !defaultSchema.equals(conn.getSchema())) {
-            conn.setSchema(defaultSchema);
-        }
-        conn.setDefaultQueryTimeout(defaultQueryTimeoutSeconds);
+    /**
+     * Sets the default "auto commit" setting for borrowed {@link Connection}s
+     *
+     * @param defaultAutoCommit
+     *            the default "auto commit" setting for borrowed {@link 
Connection}s
+     */
+    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
+        this.defaultAutoCommit = defaultAutoCommit;
     }
 
-    private void validateLifetime(final PooledObject<PoolableConnection> p) 
throws Exception {
-        if (maxConnLifetimeMillis > 0) {
-            final long lifetime = System.currentTimeMillis() - 
p.getCreateTime();
-            if (lifetime > maxConnLifetimeMillis) {
-                throw new 
LifetimeExceededException(Utils.getMessage("connectionFactory.lifetimeExceeded",
-                        Long.valueOf(lifetime), 
Long.valueOf(maxConnLifetimeMillis)));
-            }
-        }
+    /**
+     * Sets the default "catalog" setting for borrowed {@link Connection}s
+     *
+     * @param defaultCatalog
+     *            the default "catalog" setting for borrowed {@link 
Connection}s
+     */
+    public void setDefaultCatalog(final String defaultCatalog) {
+        this.defaultCatalog = defaultCatalog;
     }
 
-    protected ConnectionFactory getConnectionFactory() {
-        return connectionFactory;
+    public void setDefaultQueryTimeout(final Integer 
defaultQueryTimeoutSeconds) {
+        this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
+    }
+    /**
+     * Sets the default "read only" setting for borrowed {@link Connection}s
+     *
+     * @param defaultReadOnly
+     *            the default "read only" setting for borrowed {@link 
Connection}s
+     */
+    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
+        this.defaultReadOnly = defaultReadOnly;
     }
 
-    protected boolean getPoolStatements() {
-        return poolStatements;
+    /**
+     * Sets the default "schema" setting for borrowed {@link Connection}s
+     *
+     * @param defaultSchema
+     *            the default "schema" setting for borrowed {@link Connection}s
+     * @since 2.5.0
+     */
+    public void setDefaultSchema(final String defaultSchema) {
+        this.defaultSchema = defaultSchema;
     }
 
-    protected int getMaxOpenPreparedStatements() {
-        return maxOpenPreparedStatements;
+    /**
+     * Sets the default "Transaction Isolation" setting for borrowed {@link 
Connection}s
+     *
+     * @param defaultTransactionIsolation
+     *            the default "Transaction Isolation" setting for returned 
{@link Connection}s
+     */
+    public void setDefaultTransactionIsolation(final int 
defaultTransactionIsolation) {
+        this.defaultTransactionIsolation = defaultTransactionIsolation;
     }
 
-    protected boolean getCacheState() {
-        return cacheState;
+    /**
+     * @param disconnectionSqlCodes
+     *            The disconnection SQL codes.
+     * @see #getDisconnectionSqlCodes()
+     * @since 2.1
+     */
+    public void setDisconnectionSqlCodes(final Collection<String> 
disconnectionSqlCodes) {
+        this.disconnectionSqlCodes = disconnectionSqlCodes;
     }
 
-    protected ObjectName getDataSourceJmxName() {
-        return dataSourceJmxObjectName;
+    /**
+     * @param autoCommitOnReturn Whether to auto-commit on return.
+     * @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
+     */
+    @Deprecated
+    public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) {
+        this.autoCommitOnReturn = autoCommitOnReturn;
     }
 
-    protected AtomicLong getConnectionIndex() {
-        return connectionIndex;
+    /**
+     * @see #isFastFailValidation()
+     * @param fastFailValidation
+     *            true means connections created by this factory will fast 
fail validation
+     * @since 2.1
+     */
+    public void setFastFailValidation(final boolean fastFailValidation) {
+        this.fastFailValidation = fastFailValidation;
     }
 
-    private final ConnectionFactory connectionFactory;
-    private final ObjectName dataSourceJmxObjectName;
-    private volatile String validationQuery;
-    private volatile int validationQueryTimeoutSeconds = -1;
-    private Collection<String> connectionInitSqls;
-    private Collection<String> disconnectionSqlCodes;
-    private boolean fastFailValidation = true;
-    private volatile ObjectPool<PoolableConnection> pool;
-    private Boolean defaultReadOnly;
-    private Boolean defaultAutoCommit;
-    private boolean enableAutoCommitOnReturn = true;
-    private boolean rollbackOnReturn = true;
-    private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
-    private String defaultCatalog;
-    private String defaultSchema;
-    private boolean cacheState;
-    private boolean poolStatements;
-    private int maxOpenPreparedStatements = 
GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL_PER_KEY;
-    private long maxConnLifetimeMillis = -1;
-    private final AtomicLong connectionIndex = new AtomicLong(0);
-    private Integer defaultQueryTimeoutSeconds;
+    /**
+     * Sets the maximum lifetime in milliseconds of a connection after which 
the connection will always fail activation,
+     * passivation and validation. A value of zero or less indicates an 
infinite lifetime. The default value is -1.
+     *
+     * @param maxConnLifetimeMillis
+     *            The maximum lifetime in milliseconds.
+     */
+    public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
+        this.maxConnLifetimeMillis = maxConnLifetimeMillis;
+    }
 
     /**
-     * Internal constant to indicate the level is not set.
+     * Sets the maximum number of open prepared statements.
+     *
+     * @param maxOpenPreparedStatements
+     *            The maximum number of open prepared statements.
+     */
+    public void setMaxOpenPreparedStatements(final int 
maxOpenPreparedStatements) {
+        this.maxOpenPreparedStatements = maxOpenPreparedStatements;
+    }
+
+    /**
+     * Deprecated due to typo in method name.
+     *
+     * @param maxOpenPreparedStatements
+     *            The maximum number of open prepared statements.
+     * @deprecated Use {@link #setMaxOpenPreparedStatements(int)}.
      */
-    static final int UNKNOWN_TRANSACTIONISOLATION = -1;
+    @Deprecated // Due to typo in method name.
+    public void setMaxOpenPrepatedStatements(final int 
maxOpenPreparedStatements) {
+        setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+    }
+
+    /**
+     * Sets the {@link ObjectPool} in which to pool {@link Connection}s.
+     *
+     * @param pool
+     *            the {@link ObjectPool} in which to pool those {@link 
Connection}s
+     */
+    public synchronized void setPool(final ObjectPool<PoolableConnection> 
pool) {
+        if (null != this.pool && pool != this.pool) {
+            try {
+                this.pool.close();
+            } catch (final Exception e) {
+                // ignored !?!
+            }
+        }
+        this.pool = pool;
+    }
+
+    public void setPoolStatements(final boolean poolStatements) {
+        this.poolStatements = poolStatements;
+    }
+
+    public void setRollbackOnReturn(final boolean rollbackOnReturn) {
+        this.rollbackOnReturn = rollbackOnReturn;
+    }
+
+    /**
+     * Sets the query I use to {@link #validateObject validate} {@link 
Connection}s. Should return at least one row. If
+     * not specified, {@link Connection#isValid(int)} will be used to validate 
connections.
+     *
+     * @param validationQuery
+     *            a query to use to {@link #validateObject validate} {@link 
Connection}s.
+     */
+    public void setValidationQuery(final String validationQuery) {
+        this.validationQuery = validationQuery;
+    }
+
+    /**
+     * Sets the validation query timeout, the amount of time, in seconds, that 
connection validation will wait for a
+     * response from the database when executing a validation query. Use a 
value less than or equal to 0 for no timeout.
+     *
+     * @param validationQueryTimeoutSeconds
+     *            new validation query timeout value in seconds
+     */
+    public void setValidationQueryTimeout(final int 
validationQueryTimeoutSeconds) {
+        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
+    }
+
+    public void validateConnection(final PoolableConnection conn) throws 
SQLException {
+        if (conn.isClosed()) {
+            throw new SQLException("validateConnection: connection closed");
+        }
+        conn.validate(validationQuery, validationQueryTimeoutSeconds);
+    }
+
+    private void validateLifetime(final PooledObject<PoolableConnection> p) 
throws Exception {
+        if (maxConnLifetimeMillis > 0) {
+            final long lifetime = System.currentTimeMillis() - 
p.getCreateTime();
+            if (lifetime > maxConnLifetimeMillis) {
+                throw new 
LifetimeExceededException(Utils.getMessage("connectionFactory.lifetimeExceeded",
+                        Long.valueOf(lifetime), 
Long.valueOf(maxConnLifetimeMillis)));
+            }
+        }
+    }
+
+    @Override
+    public boolean validateObject(final PooledObject<PoolableConnection> p) {
+        try {
+            validateLifetime(p);
+
+            validateConnection(p.getObject());
+            return true;
+        } catch (final Exception e) {
+            if (log.isDebugEnabled()) {
+                
log.debug(Utils.getMessage("poolableConnectionFactory.validateObject.fail"), e);
+            }
+            return false;
+        }
+    }
 }

Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java Tue 
Jan 29 15:03:15 2019
@@ -579,7 +579,7 @@ public class PoolingConnection extends D
     }
 
     @Override
-    public String toString() {
+    public synchronized String toString() {
         if (pstmtPool != null) {
             return "PoolingConnection: " + pstmtPool.toString();
         }

Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java Tue Jan 29 
15:03:15 2019
@@ -18,9 +18,6 @@
 
 package org.apache.tomcat.dbcp.dbcp2;
 
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.Statement;
 import java.text.MessageFormat;
 import java.util.HashSet;
 import java.util.ResourceBundle;
@@ -47,9 +44,9 @@ public final class Utils {
     /**
      * SQL codes of fatal connection errors.
      * <ul>
-     * <li>57P01 (ADMIN SHUTDOWN)</li>
-     * <li>57P02 (CRASH SHUTDOWN)</li>
-     * <li>57P03 (CANNOT CONNECT NOW)</li>
+     * <li>57P01 (Admin shutdown)</li>
+     * <li>57P02 (Crash shutdown)</li>
+     * <li>57P03 (Cannot connect now)</li>
      * <li>01002 (SQL92 disconnect error)</li>
      * <li>JZ0C0 (Sybase disconnect error)</li>
      * <li>JZ0C1 (Sybase disconnect error)</li>
@@ -59,18 +56,14 @@ public final class Utils {
 
     static {
         DISCONNECTION_SQL_CODES = new HashSet<>();
-        DISCONNECTION_SQL_CODES.add("57P01"); // ADMIN SHUTDOWN
-        DISCONNECTION_SQL_CODES.add("57P02"); // CRASH SHUTDOWN
-        DISCONNECTION_SQL_CODES.add("57P03"); // CANNOT CONNECT NOW
+        DISCONNECTION_SQL_CODES.add("57P01"); // Admin shutdown
+        DISCONNECTION_SQL_CODES.add("57P02"); // Crash shutdown
+        DISCONNECTION_SQL_CODES.add("57P03"); // Cannot connect now
         DISCONNECTION_SQL_CODES.add("01002"); // SQL92 disconnect error
         DISCONNECTION_SQL_CODES.add("JZ0C0"); // Sybase disconnect error
         DISCONNECTION_SQL_CODES.add("JZ0C1"); // Sybase disconnect error
     }
 
-    private Utils() {
-        // not instantiable
-    }
-
     /**
      * Clones the given char[] if not null.
      *
@@ -83,47 +76,16 @@ public final class Utils {
     }
 
     /**
-     * Closes the ResultSet (which may be null).
-     *
-     * @param resultSet
-     *            a ResultSet, may be {@code null}
-     */
-    public static void closeQuietly(final ResultSet resultSet) {
-        if (resultSet != null) {
-            try {
-                resultSet.close();
-            } catch (final Exception e) {
-                // ignored
-            }
-        }
-    }
-
-    /**
-     * Closes the Connection (which may be null).
+     * Closes the AutoCloseable (which may be null).
      *
-     * @param connection
-     *            a Connection, may be {@code null}
+     * @param autoCloseable
+     *            an AutoCloseable, may be {@code null}
+     * @since 2.6.0
      */
-    public static void closeQuietly(final Connection connection) {
-        if (connection != null) {
+    public static void closeQuietly(final AutoCloseable autoCloseable) {
+        if (autoCloseable != null) {
             try {
-                connection.close();
-            } catch (final Exception e) {
-                // ignored
-            }
-        }
-    }
-
-    /**
-     * Closes the Statement (which may be null).
-     *
-     * @param statement
-     *            a Statement, may be {@code null}.
-     */
-    public static void closeQuietly(final Statement statement) {
-        if (statement != null) {
-            try {
-                statement.close();
+                autoCloseable.close();
             } catch (final Exception e) {
                 // ignored
             }
@@ -181,4 +143,8 @@ public final class Utils {
         return value == null ? null : String.valueOf(value);
     }
 
+    private Utils() {
+        // not instantiable
+    }
+
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
 Tue Jan 29 15:03:15 2019
@@ -730,4 +730,49 @@ public class DriverAdapterCPDS implement
             }
         }
     }
+
+    /**
+     * Does not print the userName and userPassword field nor the 'user' or 
'password' in the connectionProperties.
+     *
+     * @since 2.6.0
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder builder = new StringBuilder(super.toString());
+        builder.append("[description=");
+        builder.append(description);
+        builder.append(", url=");
+        // TODO What if the connection string contains a 'user' or 'password' 
query parameter but that connection string is not in a legal URL format?
+        builder.append(url);
+        builder.append(", driver=");
+        builder.append(driver);
+        builder.append(", loginTimeout=");
+        builder.append(loginTimeout);
+        builder.append(", poolPreparedStatements=");
+        builder.append(poolPreparedStatements);
+        builder.append(", maxIdle=");
+        builder.append(maxIdle);
+        builder.append(", timeBetweenEvictionRunsMillis=");
+        builder.append(timeBetweenEvictionRunsMillis);
+        builder.append(", numTestsPerEvictionRun=");
+        builder.append(numTestsPerEvictionRun);
+        builder.append(", minEvictableIdleTimeMillis=");
+        builder.append(minEvictableIdleTimeMillis);
+        builder.append(", maxPreparedStatements=");
+        builder.append(maxPreparedStatements);
+        builder.append(", getConnectionCalled=");
+        builder.append(getConnectionCalled);
+        builder.append(", connectionProperties=");
+        Properties tmpProps = connectionProperties;
+        final String pwdKey = "password";
+        if (connectionProperties.contains(pwdKey)) {
+            tmpProps = (Properties) connectionProperties.clone();
+            tmpProps.remove(pwdKey);
+        }
+        builder.append(tmpProps);
+        builder.append(", accessToUnderlyingConnectionAllowed=");
+        builder.append(accessToUnderlyingConnectionAllowed);
+        builder.append("]");
+        return builder.toString();
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
 Tue Jan 29 15:03:15 2019
@@ -30,6 +30,7 @@ import javax.sql.StatementEventListener;
 
 import org.apache.tomcat.dbcp.dbcp2.DelegatingConnection;
 import org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement;
+import org.apache.tomcat.dbcp.dbcp2.Jdbc41Bridge;
 import org.apache.tomcat.dbcp.dbcp2.PStmtKey;
 import org.apache.tomcat.dbcp.dbcp2.PoolableCallableStatement;
 import org.apache.tomcat.dbcp.dbcp2.PoolablePreparedStatement;
@@ -295,7 +296,7 @@ class PooledConnectionImpl
 
     private String getSchemaOrNull() {
         try {
-            return connection == null ? null : connection.getSchema();
+            return connection == null ? null : 
Jdbc41Bridge.getSchema(connection);
         } catch (final SQLException e) {
             return null;
         }
@@ -646,4 +647,30 @@ class PooledConnectionImpl
     public boolean validateObject(final PStmtKey key, final 
PooledObject<DelegatingPreparedStatement> pooledObject) {
         return true;
     }
+
+    /**
+     * @since 2.6.0
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder builder = new StringBuilder(super.toString());
+        builder.append("[connection=");
+        builder.append(connection);
+        builder.append(", delegatingConnection=");
+        builder.append(delegatingConnection);
+        builder.append(", logicalConnection=");
+        builder.append(logicalConnection);
+        builder.append(", eventListeners=");
+        builder.append(eventListeners);
+        builder.append(", statementEventListeners=");
+        builder.append(statementEventListeners);
+        builder.append(", closed=");
+        builder.append(closed);
+        builder.append(", pStmtPool=");
+        builder.append(pStmtPool);
+        builder.append(", accessToUnderlyingConnectionAllowed=");
+        builder.append(accessToUnderlyingConnectionAllowed);
+        builder.append("]");
+        return builder.toString();
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
 Tue Jan 29 15:03:15 2019
@@ -397,4 +397,30 @@ class CPDSConnectionFactory
             }
         }
     }
+
+    /**
+     * @since 2.6.0
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder builder = new StringBuilder(super.toString());
+        builder.append("[cpds=");
+        builder.append(cpds);
+        builder.append(", validationQuery=");
+        builder.append(validationQuery);
+        builder.append(", validationQueryTimeoutSeconds=");
+        builder.append(validationQueryTimeoutSeconds);
+        builder.append(", rollbackAfterValidation=");
+        builder.append(rollbackAfterValidation);
+        builder.append(", pool=");
+        builder.append(pool);
+        builder.append(", maxConnLifetimeMillis=");
+        builder.append(maxConnLifetimeMillis);
+        builder.append(", validatingSet=");
+        builder.append(validatingSet);
+        builder.append(", pcMap=");
+        builder.append(pcMap);
+        builder.append("]");
+        return builder.toString();
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
 Tue Jan 29 15:03:15 2019
@@ -1053,4 +1053,79 @@ public abstract class InstanceKeyDataSou
         }
         return cpds;
     }
+
+    /**
+     * @since 2.6.0
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder builder = new StringBuilder(super.toString());
+        builder.append("[");
+        toStringFields(builder);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    protected void toStringFields(final StringBuilder builder) {
+        builder.append("getConnectionCalled=");
+        builder.append(getConnectionCalled);
+        builder.append(", dataSource=");
+        builder.append(dataSource);
+        builder.append(", dataSourceName=");
+        builder.append(dataSourceName);
+        builder.append(", description=");
+        builder.append(description);
+        builder.append(", jndiEnvironment=");
+        builder.append(jndiEnvironment);
+        builder.append(", loginTimeout=");
+        builder.append(loginTimeout);
+        builder.append(", logWriter=");
+        builder.append(logWriter);
+        builder.append(", instanceKey=");
+        builder.append(instanceKey);
+        builder.append(", defaultBlockWhenExhausted=");
+        builder.append(defaultBlockWhenExhausted);
+        builder.append(", defaultEvictionPolicyClassName=");
+        builder.append(defaultEvictionPolicyClassName);
+        builder.append(", defaultLifo=");
+        builder.append(defaultLifo);
+        builder.append(", defaultMaxIdle=");
+        builder.append(defaultMaxIdle);
+        builder.append(", defaultMaxTotal=");
+        builder.append(defaultMaxTotal);
+        builder.append(", defaultMaxWaitMillis=");
+        builder.append(defaultMaxWaitMillis);
+        builder.append(", defaultMinEvictableIdleTimeMillis=");
+        builder.append(defaultMinEvictableIdleTimeMillis);
+        builder.append(", defaultMinIdle=");
+        builder.append(defaultMinIdle);
+        builder.append(", defaultNumTestsPerEvictionRun=");
+        builder.append(defaultNumTestsPerEvictionRun);
+        builder.append(", defaultSoftMinEvictableIdleTimeMillis=");
+        builder.append(defaultSoftMinEvictableIdleTimeMillis);
+        builder.append(", defaultTestOnCreate=");
+        builder.append(defaultTestOnCreate);
+        builder.append(", defaultTestOnBorrow=");
+        builder.append(defaultTestOnBorrow);
+        builder.append(", defaultTestOnReturn=");
+        builder.append(defaultTestOnReturn);
+        builder.append(", defaultTestWhileIdle=");
+        builder.append(defaultTestWhileIdle);
+        builder.append(", defaultTimeBetweenEvictionRunsMillis=");
+        builder.append(defaultTimeBetweenEvictionRunsMillis);
+        builder.append(", validationQuery=");
+        builder.append(validationQuery);
+        builder.append(", validationQueryTimeoutSeconds=");
+        builder.append(validationQueryTimeoutSeconds);
+        builder.append(", rollbackAfterValidation=");
+        builder.append(rollbackAfterValidation);
+        builder.append(", maxConnLifetimeMillis=");
+        builder.append(maxConnLifetimeMillis);
+        builder.append(", defaultAutoCommit=");
+        builder.append(defaultAutoCommit);
+        builder.append(", defaultTransactionIsolation=");
+        builder.append(defaultTransactionIsolation);
+        builder.append(", defaultReadOnly=");
+        builder.append(defaultReadOnly);
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
 Tue Jan 29 15:03:15 2019
@@ -235,4 +235,11 @@ public class SharedPoolDataSource extend
             throw new IOException("NamingException: " + e);
         }
     }
+
+    @Override
+    protected void toStringFields(final StringBuilder builder) {
+        super.toStringFields(builder);
+        builder.append(", maxTotal=");
+        builder.append(maxTotal);
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java 
Tue Jan 29 15:03:15 2019
@@ -125,9 +125,10 @@ class UserPassKey implements Serializabl
 
     @Override
     public String toString() {
-        final StringBuffer sb = new StringBuffer(50);
-        sb.append("UserPassKey(");
-        sb.append(userName).append(", ").append(userPassword).append(')');
+        final StringBuffer sb = new StringBuffer(super.toString());
+        sb.append("[");
+        sb.append(userName);
+        sb.append(']');
         return sb.toString();
     }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
 Tue Jan 29 15:03:15 2019
@@ -52,7 +52,7 @@ import org.apache.tomcat.dbcp.dbcp2.Util
  */
 public class BasicManagedDataSource extends BasicDataSource {
 
-    /** Transaction Registry */
+    /** Transaction Synchronization Registry */
     private TransactionRegistry transactionRegistry;
 
     /** Transaction Manager */
@@ -240,7 +240,7 @@ public class BasicManagedDataSource exte
             
connectionFactory.setMaxOpenPreparedStatements(getMaxOpenPreparedStatements());
             
connectionFactory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis());
             connectionFactory.setRollbackOnReturn(getRollbackOnReturn());
-            
connectionFactory.setEnableAutoCommitOnReturn(getEnableAutoCommitOnReturn());
+            connectionFactory.setAutoCommitOnReturn(getAutoCommitOnReturn());
             connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeout());
             connectionFactory.setFastFailValidation(getFastFailValidation());
             
connectionFactory.setDisconnectionSqlCodes(getDisconnectionSqlCodes());

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/DataSourceXAConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/DataSourceXAConnectionFactory.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/DataSourceXAConnectionFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/DataSourceXAConnectionFactory.java
 Tue Jan 29 15:03:15 2019
@@ -51,21 +51,6 @@ public class DataSourceXAConnectionFacto
      *            the transaction manager in which connections will be enlisted
      * @param xaDataSource
      *            the data source from which connections will be retrieved
-     * @param transactionSynchronizationRegistry
-     *            register with this TransactionSynchronizationRegistry
-     */
-    public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource, final 
TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
-        this(transactionManager, xaDataSource, null, (char[]) null, 
transactionSynchronizationRegistry);
-    }
-
-    /**
-     * Creates an DataSourceXAConnectionFactory which uses the specified 
XADataSource to create database connections.
-     * The connections are enlisted into transactions using the specified 
transaction manager.
-     *
-     * @param transactionManager
-     *            the transaction manager in which connections will be enlisted
-     * @param xaDataSource
-     *            the data source from which connections will be retrieved
      * @since 2.6.0
      */
     public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource) {
@@ -138,48 +123,18 @@ public class DataSourceXAConnectionFacto
     }
 
     /**
-     * Gets the user name used to authenticate new connections.
-     *
-     * @return the user name or null if unauthenticated connections are used
-     */
-    public String getUsername() {
-        return userName;
-    }
-
-    /**
-     * Sets the user name used to authenticate new connections.
-     *
-     * @param userName
-     *            the user name used for authenticating the connection or null 
for unauthenticated
-     */
-    public void setUsername(final String userName) {
-        this.userName = userName;
-    }
-
-    /**
-     * Sets the password used to authenticate new connections.
-     *
-     * @param userPassword
-     *            the password used for authenticating the connection or null 
for unauthenticated.
-     * @since 2.4.0
-     */
-    public void setPassword(final char[] userPassword) {
-        this.userPassword = userPassword;
-    }
-
-    /**
-     * Sets the password used to authenticate new connections.
+     * Creates an DataSourceXAConnectionFactory which uses the specified 
XADataSource to create database connections.
+     * The connections are enlisted into transactions using the specified 
transaction manager.
      *
-     * @param userPassword
-     *            the password used for authenticating the connection or null 
for unauthenticated
+     * @param transactionManager
+     *            the transaction manager in which connections will be enlisted
+     * @param xaDataSource
+     *            the data source from which connections will be retrieved
+     * @param transactionSynchronizationRegistry
+     *            register with this TransactionSynchronizationRegistry
      */
-    public void setPassword(final String userPassword) {
-        this.userPassword = Utils.toCharArray(userPassword);
-    }
-
-    @Override
-    public TransactionRegistry getTransactionRegistry() {
-        return transactionRegistry;
+    public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource, final 
TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
+        this(transactionManager, xaDataSource, null, (char[]) null, 
transactionSynchronizationRegistry);
     }
 
     @Override
@@ -224,4 +179,69 @@ public class DataSourceXAConnectionFacto
 
         return connection;
     }
+
+    @Override
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
+    /**
+     * Gets the user name used to authenticate new connections.
+     *
+     * @return the user name or null if unauthenticated connections are used
+     * @deprecated Use {@link #getUserName()}.
+     */
+    @Deprecated
+    public String getUsername() {
+        return userName;
+    }
+
+    /**
+     * Gets the user name used to authenticate new connections.
+     *
+     * @return the user name or null if unauthenticated connections are used
+     * @since 2.6.0
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    public char[] getUserPassword() {
+        return userPassword;
+    }
+
+    public XADataSource getXaDataSource() {
+        return xaDataSource;
+    }
+
+    /**
+     * Sets the password used to authenticate new connections.
+     *
+     * @param userPassword
+     *            the password used for authenticating the connection or null 
for unauthenticated.
+     * @since 2.4.0
+     */
+    public void setPassword(final char[] userPassword) {
+        this.userPassword = userPassword;
+    }
+
+    /**
+     * Sets the password used to authenticate new connections.
+     *
+     * @param userPassword
+     *            the password used for authenticating the connection or null 
for unauthenticated
+     */
+    public void setPassword(final String userPassword) {
+        this.userPassword = Utils.toCharArray(userPassword);
+    }
+
+    /**
+     * Sets the user name used to authenticate new connections.
+     *
+     * @param userName
+     *            the user name used for authenticating the connection or null 
for unauthenticated
+     */
+    public void setUsername(final String userName) {
+        this.userName = userName;
+    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
 Tue Jan 29 15:03:15 2019
@@ -36,45 +36,6 @@ import org.apache.tomcat.dbcp.dbcp2.Conn
  * @since 2.0
  */
 public class LocalXAConnectionFactory implements XAConnectionFactory {
-    private final TransactionRegistry transactionRegistry;
-    private final ConnectionFactory connectionFactory;
-
-    /**
-     * Creates an LocalXAConnectionFactory which uses the specified connection 
factory to create database connections.
-     * The connections are enlisted into transactions using the specified 
transaction manager.
-     *
-     * @param transactionManager
-     *            the transaction manager in which connections will be enlisted
-     * @param connectionFactory
-     *            the connection factory from which connections will be 
retrieved
-     */
-    public LocalXAConnectionFactory(final TransactionManager 
transactionManager,
-            final ConnectionFactory connectionFactory) {
-        Objects.requireNonNull(transactionManager, "transactionManager is 
null");
-        Objects.requireNonNull(connectionFactory, "connectionFactory is null");
-        this.transactionRegistry = new TransactionRegistry(transactionManager);
-        this.connectionFactory = connectionFactory;
-    }
-
-    @Override
-    public TransactionRegistry getTransactionRegistry() {
-        return transactionRegistry;
-    }
-
-    @Override
-    public Connection createConnection() throws SQLException {
-        // create a new connection
-        final Connection connection = connectionFactory.createConnection();
-
-        // create a XAResource to manage the connection during XA transactions
-        final XAResource xaResource = new LocalXAResource(connection);
-
-        // register the xa resource for the connection
-        transactionRegistry.registerConnection(connection, xaResource);
-
-        return connection;
-    }
-
     /**
      * LocalXAResource is a fake XAResource for non-XA connections. When a 
transaction is started the connection
      * auto-commit is turned off. When the connection is committed or rolled 
back, the commit or rollback method is
@@ -98,61 +59,44 @@ public class LocalXAConnectionFactory im
         }
 
         /**
-         * Gets the current xid of the transaction branch associated with this 
XAResource.
-         *
-         * @return the current xid of the transaction branch associated with 
this XAResource.
-         */
-        public synchronized Xid getXid() {
-            return currentXid;
-        }
-
-        /**
-         * Signals that a the connection has been enrolled in a transaction. 
This method saves off the current auto
-         * commit flag, and then disables auto commit. The original auto 
commit setting is restored when the transaction
-         * completes.
+         * Commits the transaction and restores the original auto commit 
setting.
          *
          * @param xid
          *            the id of the transaction branch for this connection
          * @param flag
-         *            either XAResource.TMNOFLAGS or XAResource.TMRESUME
+         *            ignored
          * @throws XAException
-         *             if the connection is already enlisted in another 
transaction, or if auto-commit could not be
-         *             disabled
+         *             if connection.commit() throws a SQLException
          */
         @Override
-        public synchronized void start(final Xid xid, final int flag) throws 
XAException {
-            if (flag == XAResource.TMNOFLAGS) {
-                // first time in this transaction
+        public synchronized void commit(final Xid xid, final boolean flag) 
throws XAException {
+            Objects.requireNonNull(xid, "xid is null");
+            if (this.currentXid == null) {
+                throw new XAException("There is no current transaction");
+            }
+            if (!this.currentXid.equals(xid)) {
+                throw new XAException("Invalid Xid: expected " + 
this.currentXid + ", but was " + xid);
+            }
 
-                // make sure we aren't already in another tx
-                if (this.currentXid != null) {
-                    throw new XAException("Already enlisted in another 
transaction with xid " + xid);
+            try {
+                // make sure the connection isn't already closed
+                if (connection.isClosed()) {
+                    throw new XAException("Connection is closed");
                 }
 
-                // save off the current auto commit flag so it can be restored 
after the transaction completes
-                try {
-                    originalAutoCommit = connection.getAutoCommit();
-                } catch (final SQLException ignored) {
-                    // no big deal, just assume it was off
-                    originalAutoCommit = true;
+                // A read only connection should not be committed
+                if (!connection.isReadOnly()) {
+                    connection.commit();
                 }
-
-                // update the auto commit flag
+            } catch (final SQLException e) {
+                throw (XAException) new XAException().initCause(e);
+            } finally {
                 try {
-                    connection.setAutoCommit(false);
+                    connection.setAutoCommit(originalAutoCommit);
                 } catch (final SQLException e) {
-                    throw (XAException) new XAException("Count not turn off 
auto commit for a XA transaction")
-                            .initCause(e);
-                }
-
-                this.currentXid = xid;
-            } else if (flag == XAResource.TMRESUME) {
-                if (!xid.equals(this.currentXid)) {
-                    throw new XAException("Attempting to resume in different 
transaction: expected " + this.currentXid
-                            + ", but was " + xid);
+                    // ignore
                 }
-            } else {
-                throw new XAException("Unknown start flag " + flag);
+                this.currentXid = null;
             }
         }
 
@@ -179,6 +123,50 @@ public class LocalXAConnectionFactory im
         }
 
         /**
+         * Clears the currently associated transaction if it is the specified 
xid.
+         *
+         * @param xid
+         *            the id of the transaction to forget
+         */
+        @Override
+        public synchronized void forget(final Xid xid) {
+            if (xid != null && xid.equals(currentXid)) {
+                currentXid = null;
+            }
+        }
+
+        /**
+         * Always returns 0 since we have no way to set a transaction timeout 
on a JDBC connection.
+         *
+         * @return always 0
+         */
+        @Override
+        public int getTransactionTimeout() {
+            return 0;
+        }
+
+        /**
+         * Gets the current xid of the transaction branch associated with this 
XAResource.
+         *
+         * @return the current xid of the transaction branch associated with 
this XAResource.
+         */
+        public synchronized Xid getXid() {
+            return currentXid;
+        }
+
+        /**
+         * Returns true if the specified XAResource == this XAResource.
+         *
+         * @param xaResource
+         *            the XAResource to test
+         * @return true if the specified XAResource == this XAResource; false 
otherwise
+         */
+        @Override
+        public boolean isSameRM(final XAResource xaResource) {
+            return this == xaResource;
+        }
+
+        /**
          * This method does nothing since the LocalXAConnection does not 
support two-phase-commit. This method will
          * return XAResource.XA_RDONLY if the connection isReadOnly(). This 
assumes that the physical connection is
          * wrapped with a proxy that prevents an application from changing the 
read-only flag while enrolled in a
@@ -210,45 +198,16 @@ public class LocalXAConnectionFactory im
         }
 
         /**
-         * Commits the transaction and restores the original auto commit 
setting.
+         * Always returns a zero length Xid array. The 
LocalXAConnectionFactory can not support recovery, so no xids
+         * will ever be found.
          *
-         * @param xid
-         *            the id of the transaction branch for this connection
          * @param flag
-         *            ignored
-         * @throws XAException
-         *             if connection.commit() throws a SQLException
+         *            ignored since recovery is not supported
+         * @return always a zero length Xid array.
          */
         @Override
-        public synchronized void commit(final Xid xid, final boolean flag) 
throws XAException {
-            Objects.requireNonNull(xid, "xid is null");
-            if (this.currentXid == null) {
-                throw new XAException("There is no current transaction");
-            }
-            if (!this.currentXid.equals(xid)) {
-                throw new XAException("Invalid Xid: expected " + 
this.currentXid + ", but was " + xid);
-            }
-
-            try {
-                // make sure the connection isn't already closed
-                if (connection.isClosed()) {
-                    throw new XAException("Connection is closed");
-                }
-
-                // A read only connection should not be committed
-                if (!connection.isReadOnly()) {
-                    connection.commit();
-                }
-            } catch (final SQLException e) {
-                throw (XAException) new XAException().initCause(e);
-            } finally {
-                try {
-                    connection.setAutoCommit(originalAutoCommit);
-                } catch (final SQLException e) {
-                    // ignore
-                }
-                this.currentXid = null;
-            }
+        public Xid[] recover(final int flag) {
+            return new Xid[0];
         }
 
         /**
@@ -281,64 +240,113 @@ public class LocalXAConnectionFactory im
         }
 
         /**
-         * Returns true if the specified XAResource == this XAResource.
+         * Always returns false since we have no way to set a transaction 
timeout on a JDBC connection.
          *
-         * @param xaResource
-         *            the XAResource to test
-         * @return true if the specified XAResource == this XAResource; false 
otherwise
+         * @param transactionTimeout
+         *            ignored since we have no way to set a transaction 
timeout on a JDBC connection
+         * @return always false
          */
         @Override
-        public boolean isSameRM(final XAResource xaResource) {
-            return this == xaResource;
+        public boolean setTransactionTimeout(final int transactionTimeout) {
+            return false;
         }
 
         /**
-         * Clears the currently associated transaction if it is the specified 
xid.
+         * Signals that a the connection has been enrolled in a transaction. 
This method saves off the current auto
+         * commit flag, and then disables auto commit. The original auto 
commit setting is restored when the transaction
+         * completes.
          *
          * @param xid
-         *            the id of the transaction to forget
+         *            the id of the transaction branch for this connection
+         * @param flag
+         *            either XAResource.TMNOFLAGS or XAResource.TMRESUME
+         * @throws XAException
+         *             if the connection is already enlisted in another 
transaction, or if auto-commit could not be
+         *             disabled
          */
         @Override
-        public synchronized void forget(final Xid xid) {
-            if (xid != null && xid.equals(currentXid)) {
-                currentXid = null;
+        public synchronized void start(final Xid xid, final int flag) throws 
XAException {
+            if (flag == XAResource.TMNOFLAGS) {
+                // first time in this transaction
+
+                // make sure we aren't already in another tx
+                if (this.currentXid != null) {
+                    throw new XAException("Already enlisted in another 
transaction with xid " + xid);
+                }
+
+                // save off the current auto commit flag so it can be restored 
after the transaction completes
+                try {
+                    originalAutoCommit = connection.getAutoCommit();
+                } catch (final SQLException ignored) {
+                    // no big deal, just assume it was off
+                    originalAutoCommit = true;
+                }
+
+                // update the auto commit flag
+                try {
+                    connection.setAutoCommit(false);
+                } catch (final SQLException e) {
+                    throw (XAException) new XAException("Count not turn off 
auto commit for a XA transaction")
+                            .initCause(e);
+                }
+
+                this.currentXid = xid;
+            } else if (flag == XAResource.TMRESUME) {
+                if (!xid.equals(this.currentXid)) {
+                    throw new XAException("Attempting to resume in different 
transaction: expected " + this.currentXid
+                            + ", but was " + xid);
+                }
+            } else {
+                throw new XAException("Unknown start flag " + flag);
             }
         }
+    }
+    private final TransactionRegistry transactionRegistry;
 
-        /**
-         * Always returns a zero length Xid array. The 
LocalXAConnectionFactory can not support recovery, so no xids
-         * will ever be found.
-         *
-         * @param flag
-         *            ignored since recovery is not supported
-         * @return always a zero length Xid array.
-         */
-        @Override
-        public Xid[] recover(final int flag) {
-            return new Xid[0];
-        }
+    private final ConnectionFactory connectionFactory;
 
-        /**
-         * Always returns 0 since we have no way to set a transaction timeout 
on a JDBC connection.
-         *
-         * @return always 0
-         */
-        @Override
-        public int getTransactionTimeout() {
-            return 0;
-        }
+    /**
+     * Creates an LocalXAConnectionFactory which uses the specified connection 
factory to create database connections.
+     * The connections are enlisted into transactions using the specified 
transaction manager.
+     *
+     * @param transactionManager
+     *            the transaction manager in which connections will be enlisted
+     * @param connectionFactory
+     *            the connection factory from which connections will be 
retrieved
+     */
+    public LocalXAConnectionFactory(final TransactionManager 
transactionManager,
+            final ConnectionFactory connectionFactory) {
+        Objects.requireNonNull(transactionManager, "transactionManager is 
null");
+        Objects.requireNonNull(connectionFactory, "connectionFactory is null");
+        this.transactionRegistry = new TransactionRegistry(transactionManager);
+        this.connectionFactory = connectionFactory;
+    }
 
-        /**
-         * Always returns false since we have no way to set a transaction 
timeout on a JDBC connection.
-         *
-         * @param transactionTimeout
-         *            ignored since we have no way to set a transaction 
timeout on a JDBC connection
-         * @return always false
-         */
-        @Override
-        public boolean setTransactionTimeout(final int transactionTimeout) {
-            return false;
-        }
+    @Override
+    public Connection createConnection() throws SQLException {
+        // create a new connection
+        final Connection connection = connectionFactory.createConnection();
+
+        // create a XAResource to manage the connection during XA transactions
+        final XAResource xaResource = new LocalXAResource(connection);
+
+        // register the xa resource for the connection
+        transactionRegistry.registerConnection(connection, xaResource);
+
+        return connection;
+    }
+
+    /**
+     * @return The connection factory.
+     * @since 2.6.0
+     */
+    public ConnectionFactory getConnectionFactory() {
+        return connectionFactory;
+    }
+
+    @Override
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
     }
 
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java 
Tue Jan 29 15:03:15 2019
@@ -46,11 +46,25 @@ import org.apache.tomcat.dbcp.pool2.Obje
  */
 public class ManagedConnection<C extends Connection> extends 
DelegatingConnection<C> {
 
+    /**
+     * Delegates to {@link ManagedConnection#transactionComplete()} for 
transaction completion events.
+     *
+     * @since 2.0
+     */
+    protected class CompletionListener implements TransactionContextListener {
+        @Override
+        public void afterCompletion(final TransactionContext completedContext, 
final boolean committed) {
+            if (completedContext == transactionContext) {
+                transactionComplete();
+            }
+        }
+    }
     private final ObjectPool<C> pool;
     private final TransactionRegistry transactionRegistry;
     private final boolean accessToUnderlyingConnectionAllowed;
     private TransactionContext transactionContext;
     private boolean isSharedConnection;
+
     private final Lock lock;
 
     /**
@@ -81,6 +95,145 @@ public class ManagedConnection<C extends
         updateTransactionStatus();
     }
 
+    @Override
+    public void close() throws SQLException {
+        if (!isClosedInternal()) {
+            // Don't actually close the connection if in a transaction. The
+            // connection will be closed by the transactionComplete method.
+            //
+            // DBCP-484 we need to make sure setClosedInternal(true) being
+            // invoked if transactionContext is not null as this value will
+            // be modified by the transactionComplete method which could run
+            // in the different thread with the transaction calling back.
+            lock.lock();
+            try {
+                if (transactionContext == null || 
transactionContext.isTransactionComplete()) {
+                    super.close();
+                }
+            } finally {
+                try {
+                    setClosedInternal(true);
+                } finally {
+                    lock.unlock();
+                }
+            }
+        }
+    }
+
+    @Override
+    public void commit() throws SQLException {
+        if (transactionContext != null) {
+            throw new SQLException("Commit can not be set while enrolled in a 
transaction");
+        }
+        super.commit();
+    }
+
+    @Override
+    public C getDelegate() {
+        if (isAccessToUnderlyingConnectionAllowed()) {
+            return getDelegateInternal();
+        }
+        return null;
+    }
+
+    //
+    // The following methods can't be used while enlisted in a transaction
+    //
+
+    @Override
+    public Connection getInnermostDelegate() {
+        if (isAccessToUnderlyingConnectionAllowed()) {
+            return super.getInnermostDelegateInternal();
+        }
+        return null;
+    }
+
+    /**
+     * @return The transaction context.
+     * @since 2.6.0
+     */
+    public TransactionContext getTransactionContext() {
+        return transactionContext;
+    }
+
+    /**
+     * @return The transaction registry.
+     * @since 2.6.0
+     */
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
+    /**
+     * If false, getDelegate() and getInnermostDelegate() will return null.
+     *
+     * @return if false, getDelegate() and getInnermostDelegate() will return 
null
+     */
+    public boolean isAccessToUnderlyingConnectionAllowed() {
+        return accessToUnderlyingConnectionAllowed;
+    }
+
+    //
+    // Methods for accessing the delegate connection
+    //
+
+    @Override
+    public void rollback() throws SQLException {
+        if (transactionContext != null) {
+            throw new SQLException("Commit can not be set while enrolled in a 
transaction");
+        }
+        super.rollback();
+    }
+
+    @Override
+    public void setAutoCommit(final boolean autoCommit) throws SQLException {
+        if (transactionContext != null) {
+            throw new SQLException("Auto-commit can not be set while enrolled 
in a transaction");
+        }
+        super.setAutoCommit(autoCommit);
+    }
+
+    @Override
+    public void setReadOnly(final boolean readOnly) throws SQLException {
+        if (transactionContext != null) {
+            throw new SQLException("Read-only can not be set while enrolled in 
a transaction");
+        }
+        super.setReadOnly(readOnly);
+    }
+
+    protected void transactionComplete() {
+        lock.lock();
+        try {
+            transactionContext.completeTransaction();
+        } finally {
+            lock.unlock();
+        }
+
+        // If we were using a shared connection, clear the reference now that
+        // the transaction has completed
+        if (isSharedConnection) {
+            setDelegate(null);
+            isSharedConnection = false;
+        }
+
+        // If this connection was closed during the transaction and there is
+        // still a delegate present close it
+        final Connection delegate = getDelegateInternal();
+        if (isClosedInternal() && delegate != null) {
+            try {
+                setDelegate(null);
+
+                if (!delegate.isClosed()) {
+                    delegate.close();
+                }
+            } catch (final SQLException ignored) {
+                // Not a whole lot we can do here as connection is closed
+                // and this is a transaction callback so there is no
+                // way to report the error.
+            }
+        }
+    }
+
     private void updateTransactionStatus() throws SQLException {
         // if there is a is an active transaction context, assure the 
transaction context hasn't changed
         if (transactionContext != null && 
!transactionContext.isTransactionComplete()) {
@@ -171,141 +324,4 @@ public class ManagedConnection<C extends
         // connection
         clearCachedState();
     }
-
-    @Override
-    public void close() throws SQLException {
-        if (!isClosedInternal()) {
-            // Don't actually close the connection if in a transaction. The
-            // connection will be closed by the transactionComplete method.
-            //
-            // DBCP-484 we need to make sure setClosedInternal(true) being
-            // invoked if transactionContext is not null as this value will
-            // be modified by the transactionComplete method which could run
-            // in the different thread with the transaction calling back.
-            lock.lock();
-            try {
-                if (transactionContext == null || 
transactionContext.isTransactionComplete()) {
-                    super.close();
-                }
-            } finally {
-                try {
-                    setClosedInternal(true);
-                } finally {
-                    lock.unlock();
-                }
-            }
-        }
-    }
-
-    /**
-     * Delegates to {@link ManagedConnection#transactionComplete()} for 
transaction completion events.
-     *
-     * @since 2.0
-     */
-    protected class CompletionListener implements TransactionContextListener {
-        @Override
-        public void afterCompletion(final TransactionContext completedContext, 
final boolean committed) {
-            if (completedContext == transactionContext) {
-                transactionComplete();
-            }
-        }
-    }
-
-    protected void transactionComplete() {
-        lock.lock();
-        try {
-            transactionContext.completeTransaction();
-        } finally {
-            lock.unlock();
-        }
-
-        // If we were using a shared connection, clear the reference now that
-        // the transaction has completed
-        if (isSharedConnection) {
-            setDelegate(null);
-            isSharedConnection = false;
-        }
-
-        // If this connection was closed during the transaction and there is
-        // still a delegate present close it
-        final Connection delegate = getDelegateInternal();
-        if (isClosedInternal() && delegate != null) {
-            try {
-                setDelegate(null);
-
-                if (!delegate.isClosed()) {
-                    delegate.close();
-                }
-            } catch (final SQLException ignored) {
-                // Not a whole lot we can do here as connection is closed
-                // and this is a transaction callback so there is no
-                // way to report the error.
-            }
-        }
-    }
-
-    //
-    // The following methods can't be used while enlisted in a transaction
-    //
-
-    @Override
-    public void setAutoCommit(final boolean autoCommit) throws SQLException {
-        if (transactionContext != null) {
-            throw new SQLException("Auto-commit can not be set while enrolled 
in a transaction");
-        }
-        super.setAutoCommit(autoCommit);
-    }
-
-    @Override
-    public void commit() throws SQLException {
-        if (transactionContext != null) {
-            throw new SQLException("Commit can not be set while enrolled in a 
transaction");
-        }
-        super.commit();
-    }
-
-    @Override
-    public void rollback() throws SQLException {
-        if (transactionContext != null) {
-            throw new SQLException("Commit can not be set while enrolled in a 
transaction");
-        }
-        super.rollback();
-    }
-
-    @Override
-    public void setReadOnly(final boolean readOnly) throws SQLException {
-        if (transactionContext != null) {
-            throw new SQLException("Read-only can not be set while enrolled in 
a transaction");
-        }
-        super.setReadOnly(readOnly);
-    }
-
-    //
-    // Methods for accessing the delegate connection
-    //
-
-    /**
-     * If false, getDelegate() and getInnermostDelegate() will return null.
-     *
-     * @return if false, getDelegate() and getInnermostDelegate() will return 
null
-     */
-    public boolean isAccessToUnderlyingConnectionAllowed() {
-        return accessToUnderlyingConnectionAllowed;
-    }
-
-    @Override
-    public C getDelegate() {
-        if (isAccessToUnderlyingConnectionAllowed()) {
-            return getDelegateInternal();
-        }
-        return null;
-    }
-
-    @Override
-    public Connection getInnermostDelegate() {
-        if (isAccessToUnderlyingConnectionAllowed()) {
-            return super.getInnermostDelegateInternal();
-        }
-        return null;
-    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedDataSource.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedDataSource.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedDataSource.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedDataSource.java 
Tue Jan 29 15:03:15 2019
@@ -52,6 +52,27 @@ public class ManagedDataSource<C extends
         this.transactionRegistry = transactionRegistry;
     }
 
+    @Override
+    public Connection getConnection() throws SQLException {
+        if (getPool() == null) {
+            throw new IllegalStateException("Pool has not been set");
+        }
+        if (transactionRegistry == null) {
+            throw new IllegalStateException("TransactionRegistry has not been 
set");
+        }
+
+        return new ManagedConnection<>(getPool(), transactionRegistry, 
isAccessToUnderlyingConnectionAllowed());
+    }
+
+    /**
+     * @return The transaction registry
+     *
+     * @since 2.6.0
+     */
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
     /**
      * Sets the transaction registry from the XAConnectionFactory used to 
create the pool. The transaction registry can
      * only be set once using either a connector or this setter method.
@@ -67,16 +88,4 @@ public class ManagedDataSource<C extends
 
         this.transactionRegistry = transactionRegistry;
     }
-
-    @Override
-    public Connection getConnection() throws SQLException {
-        if (getPool() == null) {
-            throw new IllegalStateException("Pool has not been set");
-        }
-        if (transactionRegistry == null) {
-            throw new IllegalStateException("TransactionRegistry has not been 
set");
-        }
-
-        return new ManagedConnection<>(getPool(), transactionRegistry, 
isAccessToUnderlyingConnectionAllowed());
-    }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
 Tue Jan 29 15:03:15 2019
@@ -71,6 +71,14 @@ public class PoolableManagedConnection e
     }
 
     /**
+     * @return The transaction registry.
+     * @since 2.6.0
+     */
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
+    /**
      * Actually close the underlying connection.
      */
     @Override

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
 Tue Jan 29 15:03:15 2019
@@ -57,6 +57,14 @@ public class PoolableManagedConnectionFa
     }
 
     /**
+     * @return The transaction registry.
+     * @since 2.6.0
+     */
+    public TransactionRegistry getTransactionRegistry() {
+        return transactionRegistry;
+    }
+
+    /**
      * Uses the configured XAConnectionFactory to create a {@link 
PoolableManagedConnection}. Throws
      * <code>IllegalStateException</code> if the connection factory returns 
null. Also initializes the connection using
      * configured initialization SQL (if provided) and sets up a prepared 
statement pool associated with the

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java 
Tue Jan 29 15:03:15 2019
@@ -132,7 +132,7 @@ public class TransactionContext {
     public void addTransactionContextListener(final TransactionContextListener 
listener) throws SQLException {
         try {
             if (!isActive()) {
-                Transaction transaction = this.transactionRef.get();
+                final Transaction transaction = this.transactionRef.get();
                 listener.afterCompletion(TransactionContext.this,
                         transaction == null ? false : transaction.getStatus() 
== Status.STATUS_COMMITTED);
                 return;

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1852459&r1=1852458&r2=1852459&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Jan 29 15:03:15 2019
@@ -280,6 +280,10 @@
         Update the internal fork of Apache Commons FileUpload to pick up the
         changes in the Apache Commons FileUpload 1.4 release. (markt)
       </add>
+      <update>
+        Update the internal fork of Apache Commons DBCP 2 to de20b77
+        (2019-01-29) to pick up some bug fixes and enhancements. (markt)
+      </update>
     </changelog>
   </subsection>
 </section>



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to