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=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java Thu 
Aug  9 16:50:30 2018
@@ -125,23 +125,7 @@ public class PoolingConnection extends D
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog);
-    }
-
-    protected PStmtKey createKey(final String sql, final int 
autoGeneratedKeys) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, autoGeneratedKeys);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull());
     }
 
     /**
@@ -155,13 +139,11 @@ public class PoolingConnection extends D
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, columnIndexes);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), columnIndexes);
+    }
+
+    protected PStmtKey createKey(final String sql, final int 
autoGeneratedKeys) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), autoGeneratedKeys);
     }
 
     /**
@@ -177,13 +159,7 @@ public class PoolingConnection extends D
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, 
resultSetConcurrency);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType, resultSetConcurrency);
     }
 
     /**
@@ -202,13 +178,8 @@ public class PoolingConnection extends D
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
             final int resultSetHoldability) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, 
resultSetConcurrency, resultSetHoldability);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType, resultSetConcurrency,
+                resultSetHoldability);
     }
 
     /**
@@ -222,21 +193,15 @@ public class PoolingConnection extends D
      *            result set concurrency
      * @param resultSetHoldability
      *            result set holdability
-     * @param stmtType
+     * @param statementType
      *            statement type
      *
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
-            final int resultSetHoldability, final StatementType stmtType) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, 
resultSetConcurrency, resultSetHoldability,
-                stmtType);
+            final int resultSetHoldability, final StatementType statementType) 
{
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType, resultSetConcurrency,
+                resultSetHoldability, statementType);
     }
 
     /**
@@ -248,20 +213,14 @@ public class PoolingConnection extends D
      *            result set type
      * @param resultSetConcurrency
      *            result set concurrency
-     * @param stmtType
+     * @param statementType
      *            statement type
      *
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
-            final StatementType stmtType) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, 
resultSetConcurrency, stmtType);
+            final StatementType statementType) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType, resultSetConcurrency, statementType);
     }
 
     /**
@@ -269,19 +228,13 @@ public class PoolingConnection extends D
      *
      * @param sql
      *            the SQL string used to define the statement
-     * @param stmtType
+     * @param statementType
      *            statement type
      *
      * @return the PStmtKey created for the given arguments.
      */
-    protected PStmtKey createKey(final String sql, final StatementType 
stmtType) {
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, stmtType, null);
+    protected PStmtKey createKey(final String sql, final StatementType 
statementType) {
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), statementType, null);
     }
 
     /**
@@ -295,13 +248,7 @@ public class PoolingConnection extends D
      * @return the PStmtKey created for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final String columnNames[]) 
{
-        String catalog = null;
-        try {
-            catalog = getCatalog();
-        } catch (final SQLException e) {
-            // Ignored
-        }
-        return new PStmtKey(normalizeSQL(sql), catalog, columnNames);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), columnNames);
     }
 
     /**
@@ -319,6 +266,26 @@ public class PoolingConnection extends D
         pooledObject.getObject().getInnermostDelegate().close();
     }
 
+    private String getCatalogOrNull() {
+        String catalog = null;
+        try {
+            catalog = getCatalog();
+        } catch (final SQLException e) {
+            // Ignored
+        }
+        return catalog;
+    }
+
+    private String getSchemaOrNull() {
+        String catalog = null;
+        try {
+            catalog = getSchema();
+        } catch (final SQLException e) {
+            // Ignored
+        }
+        return catalog;
+    }
+
     /**
      * {@link KeyedPooledObjectFactory} method for creating {@link 
PoolablePreparedStatement}s or
      * {@link PoolableCallableStatement}s. The <code>stmtType</code> field in 
the key determines whether a

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=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java Thu Aug  9 
16:50:30 2018
@@ -72,6 +72,17 @@ public final class Utils {
     }
 
     /**
+     * Clones the given char[] if not null.
+     *
+     * @param value
+     *            may be null.
+     * @return a cloned char[] or null.
+     */
+    public static char[] clone(final char[] value) {
+        return value == null ? null : value.clone();
+    }
+
+    /**
      * Closes the ResultSet (which may be null).
      *
      * @param resultSet
@@ -169,4 +180,5 @@ public final class Utils {
     public static String toString(final char[] value) {
         return value == null ? null : String.valueOf(value);
     }
+
 }

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -423,8 +423,8 @@ public class DriverAdapterCPDS implement
      */
     public void setPassword(final char[] userPassword) {
         assertInitializationAllowed();
-        this.userPassword = userPassword;
-        update(connectionProperties, KEY_PASSWORD, 
Utils.toString(userPassword));
+        this.userPassword = Utils.clone(userPassword);
+        update(connectionProperties, KEY_PASSWORD, 
Utils.toString(this.userPassword));
     }
 
     /**

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java?rev=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java 
Thu Aug  9 16:50:30 2018
@@ -26,27 +26,87 @@ import org.apache.tomcat.dbcp.dbcp2.PStm
  */
 @Deprecated
 public class PStmtKeyCPDS extends PStmtKey {
+
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     */
     public PStmtKeyCPDS(final String sql) {
         super(sql);
     }
 
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     * @param autoGeneratedKeys
+     *            A flag indicating whether auto-generated keys should be 
returned; one of
+     *            <code>Statement.RETURN_GENERATED_KEYS</code> or 
<code>Statement.NO_GENERATED_KEYS</code>.
+     */
     public PStmtKeyCPDS(final String sql, final int autoGeneratedKeys) {
         super(sql, null, autoGeneratedKeys);
     }
 
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     * @param resultSetType
+     *            A result set type; one of 
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *            <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or 
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+     * @param resultSetConcurrency
+     *            A concurrency type; one of 
<code>ResultSet.CONCUR_READ_ONLY</code> or
+     *            <code>ResultSet.CONCUR_UPDATABLE</code>.
+     */
     public PStmtKeyCPDS(final String sql, final int resultSetType, final int 
resultSetConcurrency) {
         super(sql, resultSetType, resultSetConcurrency);
     }
 
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     * @param resultSetType
+     *            a result set type; one of 
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+     *            <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or 
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+     * @param resultSetConcurrency
+     *            A concurrency type; one of 
<code>ResultSet.CONCUR_READ_ONLY</code> or
+     *            <code>ResultSet.CONCUR_UPDATABLE</code>
+     * @param resultSetHoldability
+     *            One of the following <code>ResultSet</code> constants: 
<code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
+     *            or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+     */
     public PStmtKeyCPDS(final String sql, final int resultSetType, final int 
resultSetConcurrency,
             final int resultSetHoldability) {
         super(sql, null, resultSetType, resultSetConcurrency, 
resultSetHoldability);
     }
 
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     * @param columnIndexes
+     *            An array of column indexes indicating the columns that 
should be returned from the inserted row or
+     *            rows.
+     */
     public PStmtKeyCPDS(final String sql, final int columnIndexes[]) {
         super(sql, null, columnIndexes);
     }
 
+    /**
+     * Constructs a key to uniquely identify a prepared statement.
+     *
+     * @param sql
+     *            The SQL statement.
+     * @param columnNames
+     *            An array of column names indicating the columns that should 
be returned from the inserted row or rows.
+     */
     public PStmtKeyCPDS(final String sql, final String columnNames[]) {
         super(sql, null, columnNames);
     }

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -182,28 +182,29 @@ class PooledConnectionImpl
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull());
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull());
     }
 
     /**
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int 
autoGeneratedKeys) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
autoGeneratedKeys);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), autoGeneratedKeys);
     }
 
     /**
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
columnIndexes);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), columnIndexes);
     }
 
     /**
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType,
+                resultSetConcurrency);
     }
 
     /**
@@ -211,8 +212,8 @@ class PooledConnectionImpl
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
             final int resultSetHoldability) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency,
-                resultSetHoldability);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType,
+                resultSetConcurrency, resultSetHoldability);
     }
 
     /**
@@ -222,8 +223,8 @@ class PooledConnectionImpl
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
             final int resultSetHoldability, final StatementType statementType) 
{
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency,
-                resultSetHoldability, statementType);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType,
+                resultSetConcurrency, resultSetHoldability, statementType);
     }
 
     /**
@@ -233,21 +234,22 @@ class PooledConnectionImpl
      */
     protected PStmtKey createKey(final String sql, final int resultSetType, 
final int resultSetConcurrency,
             final StatementType statementType) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
resultSetType, resultSetConcurrency, statementType);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), resultSetType,
+                resultSetConcurrency, statementType);
     }
 
     /**
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final StatementType 
statementType) {
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
statementType);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), statementType);
     }
 
     /**
      * Creates a {@link PStmtKey} for the given arguments.
      */
     protected PStmtKey createKey(final String sql, final String columnNames[]) 
{
-        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
columnNames);
+        return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), 
getSchemaOrNull(), columnNames);
     }
 
     /**
@@ -289,6 +291,14 @@ class PooledConnectionImpl
         } catch (final SQLException e) {
             return null;
         }
+    }
+
+    private String getSchemaOrNull() {
+        try {
+            return connection == null ? null : connection.getSchema();
+        } catch (final SQLException e) {
+            return null;
+        }
     }
 
     /**

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -123,6 +123,15 @@ class CPDSConnectionFactory
     }
 
     /**
+     * (Testing API) Gets the value of password for the default user.
+     *
+     * @return value of password.
+     */
+    char[] getPasswordCharArray() {
+        return userPassword;
+    }
+
+    /**
      * Returns the object pool used to pool connections created by this 
factory.
      *
      * @return ObjectPool managing pooled connections
@@ -336,7 +345,7 @@ class CPDSConnectionFactory
      *            new password
      */
     public synchronized void setPassword(final char[] userPassword) {
-        this.userPassword = userPassword;
+        this.userPassword =  Utils.clone(userPassword);
     }
 
     /**

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -22,6 +22,7 @@ import java.sql.SQLException;
 import javax.sql.DataSource;
 import javax.sql.XADataSource;
 import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
 
 import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
 import org.apache.tomcat.dbcp.dbcp2.ConnectionFactory;
@@ -62,6 +63,9 @@ public class BasicManagedDataSource exte
     /** XA data source instance */
     private XADataSource xaDataSourceInstance;
 
+    /** Transaction Manager */
+    private transient TransactionSynchronizationRegistry 
transactionSynchronizationRegistry;
+
     /**
      * Gets the XADataSource instance used by the XAConnectionFactory.
      *
@@ -99,6 +103,16 @@ public class BasicManagedDataSource exte
     }
 
     /**
+     * Gets the optional TransactionSynchronizationRegistry.
+     *
+     * @return the TSR that can be used to register synchronizations.
+     * @since 2.6.0
+     */
+    public TransactionSynchronizationRegistry 
getTransactionSynchronizationRegistry() {
+        return transactionSynchronizationRegistry;
+    }
+
+    /**
      * Gets the transaction registry.
      *
      * @return the transaction registry associating XAResources with managed 
connections
@@ -118,6 +132,18 @@ public class BasicManagedDataSource exte
     }
 
     /**
+     * Sets the optional TransactionSynchronizationRegistry property.
+     *
+     * @param transactionSynchronizationRegistry
+     *            the TSR used to register synchronizations
+     * @since 2.6.0
+     */
+    public void setTransactionSynchronizationRegistry(
+            final TransactionSynchronizationRegistry 
transactionSynchronizationRegistry) {
+        this.transactionSynchronizationRegistry = 
transactionSynchronizationRegistry;
+    }
+
+    /**
      * Gets the optional XADataSource class name.
      *
      * @return the optional XADataSource class name
@@ -207,6 +233,7 @@ public class BasicManagedDataSource exte
             connectionFactory.setDefaultAutoCommit(getDefaultAutoCommit());
             
connectionFactory.setDefaultTransactionIsolation(getDefaultTransactionIsolation());
             connectionFactory.setDefaultCatalog(getDefaultCatalog());
+            connectionFactory.setDefaultSchema(getDefaultSchema());
             connectionFactory.setCacheState(getCacheState());
             connectionFactory.setPoolStatements(isPoolPreparedStatements());
             
connectionFactory.setMaxOpenPreparedStatements(getMaxOpenPreparedStatements());

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -27,6 +27,7 @@ import javax.sql.PooledConnection;
 import javax.sql.XAConnection;
 import javax.sql.XADataSource;
 import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
 import javax.transaction.xa.XAResource;
 
 import org.apache.tomcat.dbcp.dbcp2.Utils;
@@ -50,9 +51,25 @@ 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) {
-        this(transactionManager, xaDataSource, null, (char[]) null);
+        this(transactionManager, xaDataSource, null, (char[]) null, null);
     }
 
     /**
@@ -70,9 +87,33 @@ public class DataSourceXAConnectionFacto
      */
     public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource,
             final String userName, final char[] userPassword) {
+        this(transactionManager, xaDataSource, userName, userPassword, null);
+    }
+
+    /**
+     * 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
+     * @param userName
+     *            the user name used for authenticating new connections or 
null for unauthenticated
+     * @param userPassword
+     *            the password used for authenticating new connections
+     * @param transactionSynchronizationRegistry
+     *            register with this TransactionSynchronizationRegistry
+     * @since 2.6.0
+     */
+    public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource,
+            final String userName, final char[] userPassword, final 
TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
         Objects.requireNonNull(transactionManager, "transactionManager is 
null");
         Objects.requireNonNull(xaDataSource, "xaDataSource is null");
-        this.transactionRegistry = new TransactionRegistry(transactionManager);
+
+        // We do allow the transactionSynchronizationRegistry to be null for 
non-app server environments
+
+        this.transactionRegistry = new TransactionRegistry(transactionManager, 
transactionSynchronizationRegistry);
         this.xaDataSource = xaDataSource;
         this.userName = userName;
         this.userPassword = userPassword;
@@ -93,7 +134,7 @@ public class DataSourceXAConnectionFacto
      */
     public DataSourceXAConnectionFactory(final TransactionManager 
transactionManager, final XADataSource xaDataSource,
             final String userName, final String userPassword) {
-        this(transactionManager, xaDataSource, userName, 
Utils.toCharArray(userPassword));
+        this(transactionManager, xaDataSource, userName, 
Utils.toCharArray(userPassword), null);
     }
 
     /**

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=1837746&r1=1837745&r2=1837746&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 
Thu Aug  9 16:50:30 2018
@@ -105,9 +105,10 @@ public class ManagedConnection<C extends
             // in the transaction, replace our delegate with the enrolled 
connection
 
             // return current connection to the pool
+            @SuppressWarnings("resource")
             final C connection = getDelegateInternal();
             setDelegate(null);
-            if (connection != null) {
+            if (connection != null && transactionContext.getSharedConnection() 
!= connection) {
                 try {
                     pool.returnObject(connection);
                 } catch (final Exception ignored) {

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=1837746&r1=1837745&r2=1837746&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
 Thu Aug  9 16:50:30 2018
@@ -45,7 +45,7 @@ public class PoolableManagedConnection e
      */
     public PoolableManagedConnection(final TransactionRegistry 
transactionRegistry, final Connection conn,
             final ObjectPool<PoolableConnection> pool) {
-        this(transactionRegistry, conn, pool, null, false);
+        this(transactionRegistry, conn, pool, null, true);
     }
 
     /**

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=1837746&r1=1837745&r2=1837746&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 
Thu Aug  9 16:50:30 2018
@@ -27,6 +27,7 @@ import javax.transaction.Status;
 import javax.transaction.Synchronization;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
+import javax.transaction.TransactionSynchronizationRegistry;
 import javax.transaction.xa.XAResource;
 
 /**
@@ -39,6 +40,7 @@ import javax.transaction.xa.XAResource;
 public class TransactionContext {
     private final TransactionRegistry transactionRegistry;
     private final WeakReference<Transaction> transactionRef;
+    private final TransactionSynchronizationRegistry 
transactionSynchronizationRegistry;
     private Connection sharedConnection;
     private boolean transactionComplete;
 
@@ -50,13 +52,29 @@ public class TransactionContext {
      *            the TransactionRegistry used to obtain the XAResource for 
the shared connection
      * @param transaction
      *            the transaction
+     * @param transactionSynchronizationRegistry
+     *              The optional TSR to register synchronizations with
+     * @since 2.6.0
      */
-    public TransactionContext(final TransactionRegistry transactionRegistry, 
final Transaction transaction) {
+    public TransactionContext(final TransactionRegistry transactionRegistry, 
final Transaction transaction,
+                              final TransactionSynchronizationRegistry 
transactionSynchronizationRegistry) {
         Objects.requireNonNull(transactionRegistry, "transactionRegistry is 
null");
         Objects.requireNonNull(transaction, "transaction is null");
         this.transactionRegistry = transactionRegistry;
         this.transactionRef = new WeakReference<>(transaction);
         this.transactionComplete = false;
+        this.transactionSynchronizationRegistry = 
transactionSynchronizationRegistry;
+    }
+
+    /**
+     * Provided for backwards compatability
+     *
+     * @param transactionRegistry the TransactionRegistry used to obtain the 
XAResource for the
+     * shared connection
+     * @param transaction the transaction
+     */
+    public TransactionContext(final TransactionRegistry transactionRegistry, 
final Transaction transaction) {
+        this (transactionRegistry, transaction, null);
     }
 
     /**
@@ -113,7 +131,13 @@ public class TransactionContext {
      */
     public void addTransactionContextListener(final TransactionContextListener 
listener) throws SQLException {
         try {
-            getTransaction().registerSynchronization(new Synchronization() {
+            if (!isActive()) {
+                Transaction transaction = this.transactionRef.get();
+                listener.afterCompletion(TransactionContext.this,
+                        transaction == null ? false : transaction.getStatus() 
== Status.STATUS_COMMITTED);
+                return;
+            }
+            final Synchronization s = new Synchronization() {
                 @Override
                 public void beforeCompletion() {
                     // empty
@@ -123,7 +147,12 @@ public class TransactionContext {
                 public void afterCompletion(final int status) {
                     listener.afterCompletion(TransactionContext.this, status 
== Status.STATUS_COMMITTED);
                 }
-            });
+            };
+            if (transactionSynchronizationRegistry != null) {
+                
transactionSynchronizationRegistry.registerInterposedSynchronization(s);
+            } else {
+                getTransaction().registerSynchronization(s);
+            }
         } catch (final RollbackException e) {
             // JTA spec doesn't let us register with a transaction marked 
rollback only
             // just ignore this and the tx state will be cleared another way.

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionRegistry.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionRegistry.java?rev=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionRegistry.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionRegistry.java 
Thu Aug  9 16:50:30 2018
@@ -26,6 +26,7 @@ import java.util.WeakHashMap;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
 import javax.transaction.xa.XAResource;
 
 import org.apache.tomcat.dbcp.dbcp2.DelegatingConnection;
@@ -43,15 +44,28 @@ public class TransactionRegistry {
     private final TransactionManager transactionManager;
     private final Map<Transaction, TransactionContext> caches = new 
WeakHashMap<>();
     private final Map<Connection, XAResource> xaResources = new 
WeakHashMap<>();
+    private final TransactionSynchronizationRegistry 
transactionSynchronizationRegistry;
 
     /**
      * Creates a TransactionRegistry for the specified transaction manager.
      *
      * @param transactionManager
      *            the transaction manager used to enlist connections.
+     * @param transactionSynchronizationRegistry
+     *              The optional TSR to register synchronizations with
+     * @since 2.6.0
      */
-    public TransactionRegistry(final TransactionManager transactionManager) {
+    public TransactionRegistry(final TransactionManager transactionManager, 
final TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
         this.transactionManager = transactionManager;
+        this.transactionSynchronizationRegistry = 
transactionSynchronizationRegistry;
+    }
+
+    /**
+     * Provided for backwards compatability
+     * @param transactionManager the transaction manager used to enlist 
connections
+     */
+    public TransactionRegistry(final TransactionManager transactionManager) {
+        this (transactionManager, null);
     }
 
     /**
@@ -111,11 +125,11 @@ public class TransactionRegistry {
             throw new SQLException("Unable to determine current transaction ", 
e);
         }
 
-        // register the the context (or create a new one)
+        // register the context (or create a new one)
         synchronized (this) {
             TransactionContext cache = caches.get(transaction);
             if (cache == null) {
-                cache = new TransactionContext(this, transaction);
+                cache = new TransactionContext(this, transaction, 
transactionSynchronizationRegistry);
                 caches.put(transaction, cache);
             }
             return cache;

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java?rev=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java 
Thu Aug  9 16:50:30 2018
@@ -26,7 +26,7 @@ import org.apache.tomcat.dbcp.dbcp2.Conn
  * XAConnectionFactory is an extension of ConnectionFactory used to create 
connections in a transaction managed
  * environment. The XAConnectionFactory operates like a normal 
ConnectionFactory except a TransactionRegistry is
  * provided from which the XAResource for a connection can be obtained. This 
allows the existing DBCP pool code to work
- * with XAConnections and gives a the ManagedConnection a way to enlist a 
connection in the the transaction.
+ * with XAConnections and gives a the ManagedConnection a way to enlist a 
connection in the transaction.
  *
  * @since 2.0
  */

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1837746&r1=1837745&r2=1837746&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Aug  9 16:50:30 2018
@@ -244,6 +244,10 @@
         Update the internal fork of Apache Commons Pool 2 to 3e02523
         (2018-08-09) to pick up some bug fixes and enhancements. (markt)
       </update>
+      <update>
+        Update the internal fork of Apache Commons DBCP 2 to abc0484
+        (2018-08-09) to pick up some bug fixes and enhancements. (markt)
+      </update>
     </changelog>
   </subsection>
 </section>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to