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