/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomcat.dbcp.dbcp2; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Properties; import java.util.Set; import java.util.logging.Logger; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.sql.DataSource; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.dbcp.pool2.PooledObject; import org.apache.tomcat.dbcp.pool2.impl.AbandonedConfig; import org.apache.tomcat.dbcp.pool2.impl.BaseObjectPoolConfig; import org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPoolConfig; import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool; import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig; /** *
* Basic implementation of javax.sql.DataSource that is configured via JavaBeans properties. This is not
* the only way to combine the commons-dbcp2 and commons-pool2 packages, but provides a "one stop
* shopping" solution for basic requirements.
*
true both PreparedStatements
* and CallableStatements are pooled.
*/
private boolean poolPreparedStatements = false;
/**
* * The maximum number of open statements that can be allocated from the statement pool at the same time, or negative * for no limit. Since a connection usually only uses one or two statements at a time, this is mostly used to help * detect resource leaks. *
*
* Note: As of version 1.3, CallableStatements (those produced by {@link Connection#prepareCall}) are pooled along
* with PreparedStatements (produced by {@link Connection#prepareStatement}) and
* maxOpenPreparedStatements limits the total number of prepared or callable statements that may be in
* use at a given time.
*
* This property can be used for example to run ALTER SESSION SET NLS_SORT=XCYECH in an Oracle Database only once * after connection creation. *
*/ private volatile ListcreateDataSource() method.
*/
private volatile DataSource dataSource;
/**
* The PrintWriter to which log messages should be directed.
*/
private volatile PrintWriter logWriter = new PrintWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
private AbandonedConfig abandonedConfig;
private boolean closed;
/**
* Actual name under which this component has been registered.
*/
private ObjectNameWrapper registeredJmxObjectName;
/**
* Adds a custom connection property to the set that will be passed to our JDBC driver. This MUST
* be called before the first connection is retrieved (along with all the other configuration property setters).
* Calls to this method after the connection pool has been initialized have no effect.
*
* @param name Name of the custom connection property
* @param value Value of the custom connection property
*/
public void addConnectionProperty(final String name, final String value) {
connectionProperties.put(name, value);
}
/**
* * Closes and releases all idle connections that are currently stored in the connection pool associated with this * data source. *
** Connections that are checked out to clients when this method is invoked are not affected. When client * applications subsequently invoke {@link Connection#close()} to return these connections to the pool, the * underlying JDBC connections are closed. *
** Attempts to acquire connections using {@link #getConnection()} after this method has been invoked result in * SQLExceptions. *
** This method is idempotent - i.e., closing an already closed BasicDataSource has no effect and does not generate * exceptions. *
* * @throws SQLException if an error occurs closing idle connections */ @Override public synchronized void close() throws SQLException { if (registeredJmxObjectName != null) { registeredJmxObjectName.unregisterMBean(); registeredJmxObjectName = null; } closed = true; final GenericObjectPool> oldPool = connectionPool; connectionPool = null; dataSource = null; try { if (oldPool != null) { oldPool.close(); } } catch (final RuntimeException e) { throw e; } catch (final Exception e) { throw new SQLException(Utils.getMessage("pool.close.fail"), e); } } /** * Closes the connection pool, silently swallowing any exception that occurs. */ private void closeConnectionPool() { final GenericObjectPool> oldPool = connectionPool; connectionPool = null; try { if (oldPool != null) { oldPool.close(); } } catch (final Exception e) { /* Ignore */ } } /** * Creates a JDBC connection factory for this datasource. The JDBC driver is loaded using the following algorithm: ** This method exists so subclasses can replace the implementation class. *
* * @return A new connection factory. * * @throws SQLException If the connection factort cannot be created */ protected ConnectionFactory createConnectionFactory() throws SQLException { // Load the JDBC driver class return ConnectionFactoryFactory.createConnectionFactory(this, DriverFactory.createDriver(this)); } /** * Creates a connection pool for this datasource. This method only exists so subclasses can replace the * implementation class. ** This implementation configures all pool properties other than timeBetweenEvictionRunsMillis. Setting that * property is deferred to {@link #startPoolMaintenance()}, since setting timeBetweenEvictionRunsMillis to a * positive value causes {@link GenericObjectPool}'s eviction timer to be started. *
* * @param factory The factory to use to create new connections for this pool. */ protected void createConnectionPool(final PoolableConnectionFactory factory) { // Create an object pool to contain our active connections final GenericObjectPoolConfig* Creates (if necessary) and return the internal data source we are using to manage our connections. *
* * @return The current internal DataSource or a newly created instance if it has not yet been created. * @throws SQLException if the object pool cannot be created. */ protected DataSource createDataSource() throws SQLException { if (closed) { throw new SQLException("Data source is closed"); } // Return the pool if we have already created it // This is double-checked locking. This is safe since dataSource is // volatile and the code is targeted at Java 5 onwards. if (dataSource != null) { return dataSource; } synchronized (this) { if (dataSource != null) { return dataSource; } jmxRegister(); // create factory which returns raw physical connections final ConnectionFactory driverConnectionFactory = createConnectionFactory(); // Set up the poolable connection factory boolean success = false; PoolableConnectionFactory poolableConnectionFactory; try { poolableConnectionFactory = createPoolableConnectionFactory(driverConnectionFactory); poolableConnectionFactory.setPoolStatements(poolPreparedStatements); poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements); success = true; } catch (final SQLException se) { throw se; } catch (final RuntimeException rte) { throw rte; } catch (final Exception ex) { throw new SQLException("Error creating connection factory", ex); } if (success) { // create a pool for our connections createConnectionPool(poolableConnectionFactory); } // Create the pooling data source to manage connections DataSource newDataSource; success = false; try { newDataSource = createDataSourceInstance(); newDataSource.setLogWriter(logWriter); success = true; } catch (final SQLException se) { throw se; } catch (final RuntimeException rte) { throw rte; } catch (final Exception ex) { throw new SQLException("Error creating datasource", ex); } finally { if (!success) { closeConnectionPool(); } } // If initialSize > 0, preload the pool try { for (int i = 0; i < initialSize; i++) { connectionPool.addObject(); } } catch (final Exception e) { closeConnectionPool(); throw new SQLException("Error preloading the connection pool", e); } // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor // task startPoolMaintenance(); dataSource = newDataSource; return dataSource; } } /** * Creates the actual data source instance. This method only exists so that subclasses can replace the * implementation class. * * @throws SQLException if unable to create a datasource instance * * @return A new DataSource instance */ protected DataSource createDataSourceInstance() throws SQLException { final PoolingDataSourcetrue if usage tracking is enabled
*/
@Override
public boolean getAbandonedUsageTracking() {
if (abandonedConfig != null) {
return abandonedConfig.getUseUsageTracking();
}
return false;
}
/**
* Returns the value of the flag that controls whether or not connections being returned to the pool will be checked
* and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit
* setting is {@code false} when the connection is returned. It is true by default.
*
* @return Whether or not connections being returned to the pool will be checked and configured with auto-commit.
*/
public boolean getAutoCommitOnReturn() {
return autoCommitOnReturn;
}
/**
* Returns the state caching flag.
*
* @return the state caching flag
*/
@Override
public boolean getCacheState() {
return cacheState;
}
/**
* Creates (if necessary) and return a connection to the database.
*
* @throws SQLException if a database access error occurs
* @return a database connection
*/
@Override
public Connection getConnection() throws SQLException {
if (Utils.IS_SECURITY_ENABLED) {
final PrivilegedExceptionAction* Note: This getter only returns the last value set by a call to {@link #setConnectionFactoryClassName(String)}. *
* * @return the ConnectionFactoryClassName that has been configured for use by this pool. * @since 2.7.0 */ public String getConnectionFactoryClassName() { return this.connectionFactoryClassName; } /** * Returns the list of SQL statements executed when a physical connection is first created. Returns an empty list if * there are no initialization statements configured. * * @return initialization SQL statements */ public Listnull means that the driver default will be used.
*
* @return The default query timeout in seconds.
*/
public Integer getDefaultQueryTimeout() {
return defaultQueryTimeoutSeconds;
}
/**
* Returns the default readOnly property.
*
* @return true if connections are readOnly by default
*/
@Override
public Boolean getDefaultReadOnly() {
return defaultReadOnly;
}
/**
* Returns the default schema.
*
* @return the default schema.
* @since 2.5.0
*/
@Override
public String getDefaultSchema() {
return this.defaultSchema;
}
/**
* Returns the default transaction isolation state of returned connections.
*
* @return the default value for transaction isolation state
* @see Connection#getTransactionIsolation
*/
@Override
public int getDefaultTransactionIsolation() {
return this.defaultTransactionIsolation;
}
/**
* Returns the set of SQL_STATE codes considered to signal fatal conditions.
*
* @return fatal disconnection state codes
* @see #setDisconnectionSqlCodes(Collection)
* @since 2.1
*/
public Set* Note: This getter only returns the last value set by a call to {@link #setDriver(Driver)}. It does not return any * driver instance that may have been created from the value set via {@link #setDriverClassName(String)}. *
* * @return the JDBC Driver that has been configured for use by this pool */ public synchronized Driver getDriver() { return driver; } /** * Returns the class loader specified for loading the JDBC driver. Returnsnull if no class loader has
* been explicitly specified.
* * Note: This getter only returns the last value set by a call to {@link #setDriverClassLoader(ClassLoader)}. It * does not return the class loader of any driver that may have been set via {@link #setDriver(Driver)}. *
* * @return The class loader specified for loading the JDBC driver. */ public synchronized ClassLoader getDriverClassLoader() { return this.driverClassLoader; } /** * Returns the JDBC driver class name. ** Note: This getter only returns the last value set by a call to {@link #setDriverClassName(String)}. It does not * return the class name of any driver that may have been set via {@link #setDriver(Driver)}. *
* * @return the JDBC driver class name */ @Override public synchronized String getDriverClassName() { return this.driverClassName; } /** * Returns the value of the flag that controls whether or not connections being returned to the pool will be checked * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit * setting is {@code false} when the connection is returned. It istrue by default.
*
* @return Whether or not connections being returned to the pool will be checked and configured with auto-commit.
* @deprecated Use {@link #getAutoCommitOnReturn()}.
*/
@Deprecated
public boolean getEnableAutoCommitOnReturn() {
return autoCommitOnReturn;
}
/**
* Gets the EvictionPolicy implementation in use with this connection pool.
*
* @return The EvictionPolicy implementation in use with this connection pool.
*/
public synchronized String getEvictionPolicyClassName() {
return evictionPolicyClassName;
}
/**
* 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 datasource will fast fail validation.
* @see #setDisconnectionSqlCodes(Collection)
* @since 2.1
*/
@Override
public boolean getFastFailValidation() {
return fastFailValidation;
}
/**
* Returns the initial size of the connection pool.
*
* @return the number of connections created when the pool is initialized
*/
@Override
public synchronized int getInitialSize() {
return this.initialSize;
}
/**
* Returns the JMX name that has been requested for this DataSource. If the requested name is not valid, an
* alternative may be chosen.
*
* @return The JMX name that has been requested for this DataSource.
*/
public String getJmxName() {
return jmxName;
}
/**
* Returns the LIFO property.
*
* @return true if connection pool behaves as a LIFO queue.
*/
@Override
public synchronized boolean getLifo() {
return this.lifo;
}
/**
* * Flag to log stack traces for application code which abandoned a Statement or Connection. *
** Defaults to false. *
** Logging of abandoned Statements and Connections adds overhead for every Connection open or new Statement because * a stack trace has to be generated. *
*/ @Override public boolean getLogAbandoned() { if (abandonedConfig != null) { return abandonedConfig.getLogAbandoned(); } return false; } /** * When {@link #getMaxConnLifetimeMillis()} is set to limit connection lifetime, this property determines whether or * not log messages are generated when the pool closes connections due to maximum lifetime exceeded. * * @since 2.1 */ @Override public boolean getLogExpiredConnections() { return logExpiredConnections; } /** * BasicDataSource does NOT support this method. * ** Returns the login timeout (in seconds) for connecting to the database. *
** Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. *
* * @throws SQLException if a database access error occurs * @throws UnsupportedOperationException If the DataSource implementation does not support the login timeout * feature. * @return login timeout in seconds */ @Override public int getLoginTimeout() throws SQLException { // This method isn't supported by the PoolingDataSource returned by the // createDataSource throw new UnsupportedOperationException("Not supported by BasicDataSource"); } /** ** Returns the log writer being used by this data source. *
** Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. *
* * @throws SQLException if a database access error occurs * @return log writer in use */ @Override public PrintWriter getLogWriter() throws SQLException { return createDataSource().getLogWriter(); } /** * Returns the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an * infinite lifetime. */ @Override public long getMaxConnLifetimeMillis() { return maxConnLifetimeMillis; } /** ** Returns the maximum number of connections that can remain idle in the pool. Excess idle connections are destroyed * on return to the pool. *
** A negative value indicates that there is no limit *
* * @return the maximum number of idle connections */ @Override public synchronized int getMaxIdle() { return this.maxIdle; } /** * Gets the value of themaxOpenPreparedStatements property.
*
* @return the maximum number of open statements
*/
@Override
public synchronized int getMaxOpenPreparedStatements() {
return this.maxOpenPreparedStatements;
}
/**
* * Returns the maximum number of active connections that can be allocated at the same time. *
** A negative number means that there is no limit. *
* * @return the maximum number of active connections */ @Override public synchronized int getMaxTotal() { return this.maxTotal; } /** * Returns the maximum number of milliseconds that the pool will wait for a connection to be returned before * throwing an exception. A value less than or equal to zero means the pool is set to wait indefinitely. * * @return the maxWaitMillis property value */ @Override public synchronized long getMaxWaitMillis() { return this.maxWaitMillis; } /** * Returns the {@link #minEvictableIdleTimeMillis} property. * * @return the value of the {@link #minEvictableIdleTimeMillis} property * @see #minEvictableIdleTimeMillis */ @Override public synchronized long getMinEvictableIdleTimeMillis() { return this.minEvictableIdleTimeMillis; } /** * Returns the minimum number of idle connections in the pool. The pool attempts to ensure that minIdle connections * are available when the idle object evictor runs. The value of this property has no effect unless * {@link #timeBetweenEvictionRunsMillis} has a positive value. * * @return the minimum number of idle connections * @see GenericObjectPool#getMinIdle() */ @Override public synchronized int getMinIdle() { return this.minIdle; } /** * [Read Only] The current number of active connections that have been allocated from this data source. * * @return the current number of active connections */ @Override public int getNumActive() { // Copy reference to avoid NPE if close happens after null check final GenericObjectPool* Flag to remove abandoned connections if they exceed the removeAbandonedTimeout when borrowObject is invoked. *
** The default value is false. *
** If set to true a connection is considered abandoned and eligible for removal if it has not been used for more * than {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds. *
** Abandoned connections are identified and removed when {@link #getConnection()} is invoked and all of the * following conditions hold: *
** Flag to remove abandoned connections if they exceed the removeAbandonedTimeout during pool maintenance. *
* ** The default value is false. *
* ** If set to true a connection is considered abandoned and eligible for removal if it has not been used for more * than {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds. *
* * @see #getRemoveAbandonedTimeout() */ @Override public boolean getRemoveAbandonedOnMaintenance() { if (abandonedConfig != null) { return abandonedConfig.getRemoveAbandonedOnMaintenance(); } return false; } /** ** Timeout in seconds before an abandoned connection can be removed. *
** Creating a Statement, PreparedStatement or CallableStatement or using one of these to execute a query (using one * of the execute methods) resets the lastUsed property of the parent connection. *
** Abandoned connection cleanup happens when: *
** The default value is 300 seconds. *
*/ @Override public int getRemoveAbandonedTimeout() { if (abandonedConfig != null) { return abandonedConfig.getRemoveAbandonedTimeout(); } return 300; } /** * Gets the current value of the flag that controls whether a connection will be rolled back when it is returned to * the pool if auto commit is not enabled and the connection is not read only. * * @return whether a connection will be rolled back when it is returned to the pool. */ public boolean getRollbackOnReturn() { return rollbackOnReturn; } /** ** Returns the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by * the idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. *
* ** When {@link #getMinEvictableIdleTimeMillis() minEvictableIdleTimeMillis} is set to a positive value, * minEvictableIdleTimeMillis is examined first by the idle connection evictor - i.e. when idle connections are * visited by the evictor, idle time is first compared against {@code minEvictableIdleTimeMillis} (without * considering the number of idle connections in the pool) and then against {@code softMinEvictableIdleTimeMillis}, * including the {@code minIdle}, constraint. *
* * @return minimum amount of time a connection may sit idle in the pool before it is eligible for eviction, assuming * there are minIdle idle connections in the pool */ @Override public synchronized long getSoftMinEvictableIdleTimeMillis() { return softMinEvictableIdleTimeMillis; } /** * Returns the {@link #testOnBorrow} property. * * @return true if objects are validated before being borrowed from the pool * * @see #testOnBorrow */ @Override public synchronized boolean getTestOnBorrow() { return this.testOnBorrow; } /** * Returns the {@link #testOnCreate} property. * * @return true if objects are validated immediately after they are created by the pool * @see #testOnCreate */ @Override public synchronized boolean getTestOnCreate() { return this.testOnCreate; } /** * Returns the value of the {@link #testOnReturn} property. * * @return true if objects are validated before being returned to the pool * @see #testOnReturn */ public synchronized boolean getTestOnReturn() { return this.testOnReturn; } /** * Returns the value of the {@link #testWhileIdle} property. * * @return true if objects examined by the idle object evictor are validated * @see #testWhileIdle */ @Override public synchronized boolean getTestWhileIdle() { return this.testWhileIdle; } /** * Returns the value of the {@link #timeBetweenEvictionRunsMillis} property. * * @return the time (in milliseconds) between evictor runs * @see #timeBetweenEvictionRunsMillis */ @Override public synchronized long getTimeBetweenEvictionRunsMillis() { return this.timeBetweenEvictionRunsMillis; } /** * Returns the JDBC connection {@link #url} property. * * @return the {@link #url} passed to the JDBC driver to establish connections */ @Override public synchronized String getUrl() { return this.url; } /** * Returns the JDBC connection {@link #userName} property. * * @return the {@link #userName} passed to the JDBC driver to establish connections */ @Override public String getUsername() { return this.userName; } /** * Returns the validation query used to validate connections before returning them. * * @return the SQL validation query * @see #validationQuery */ @Override public String getValidationQuery() { return this.validationQuery; } /** * Returns the validation query timeout. * * @return the timeout in seconds before connection validation queries fail. */ @Override public int getValidationQueryTimeout() { return validationQueryTimeoutSeconds; } /** * Manually invalidates a connection, effectively requesting the pool to try to close it, remove it from the pool * and reclaim pool capacity. * * @param connection The Connection to invalidate. * * @throws IllegalStateException if invalidating the connection failed. * @since 2.1 */ @SuppressWarnings("resource") public void invalidateConnection(final Connection connection) throws IllegalStateException { if (connection == null) { return; } if (connectionPool == null) { throw new IllegalStateException("Cannot invalidate connection: ConnectionPool is null."); } final PoolableConnection poolableConnection; try { poolableConnection = connection.unwrap(PoolableConnection.class); if (poolableConnection == null) { throw new IllegalStateException( "Cannot invalidate connection: Connection is not a poolable connection."); } } catch (final SQLException e) { throw new IllegalStateException("Cannot invalidate connection: Unwrapping poolable connection failed.", e); } try { connectionPool.invalidateObject(poolableConnection); } catch (final Exception e) { throw new IllegalStateException("Invalidating connection threw unexpected exception", e); } } /** * Returns the value of the accessToUnderlyingConnectionAllowed property. * * @return true if access to the underlying connection is allowed, false otherwise. */ @Override public synchronized boolean isAccessToUnderlyingConnectionAllowed() { return this.accessToUnderlyingConnectionAllowed; } /** * If true, this data source is closed and no more connections can be retrieved from this datasource. * * @return true, if the data source is closed; false otherwise */ @Override public synchronized boolean isClosed() { return closed; } /** * Delegates in a null-safe manner to {@link String#isEmpty()}. * * @param value the string to test, may be null. * @return boolean false if value is null, otherwise {@link String#isEmpty()}. */ private boolean isEmpty(String value) { return value == null ? true : value.trim().isEmpty(); } /** * Returns true if we are pooling statements. * * @return true if prepared and callable statements are pooled */ @Override public synchronized boolean isPoolPreparedStatements() { return this.poolPreparedStatements; } @Override public boolean isWrapperFor(final Class> iface) throws SQLException { return false; } private void jmxRegister() { // Return immediately if this DataSource has already been registered if (registeredJmxObjectName != null) { return; } // Return immediately if no JMX name has been specified final String requestedName = getJmxName(); if (requestedName == null) { return; } try { ObjectNameWrapper.wrap(requestedName).registerMBean(this); } catch (final MalformedObjectNameException e) { log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored."); } } protected void log(final String message) { if (logWriter != null) { logWriter.println(message); } } /** * Logs the given throwable. * @param message TODO * @param throwable the throwable. * * @since 2.7.0 */ protected void log(String message, Throwable throwable) { if (logWriter != null) { logWriter.println(message); throwable.printStackTrace(logWriter); } } @Override public void postDeregister() { // NO-OP } @Override public void postRegister(final Boolean registrationDone) { // NO-OP } @Override public void preDeregister() throws Exception { // NO-OP } @Override public ObjectName preRegister(final MBeanServer server, final ObjectName objectName) { final String requestedName = getJmxName(); if (requestedName != null) { try { registeredJmxObjectName = ObjectNameWrapper.wrap(requestedName); } catch (final MalformedObjectNameException e) { log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored."); } } if (registeredJmxObjectName == null) { registeredJmxObjectName = ObjectNameWrapper.wrap(objectName); } return ObjectNameWrapper.unwrap(registeredJmxObjectName); } /** * Removes a custom connection property. * * @param name Name of the custom connection property to remove * @see #addConnectionProperty(String, String) */ public void removeConnectionProperty(final String name) { connectionProperties.remove(name); } /** * Sets the print writer to be used by this configuration to log information on abandoned objects. * * @param logWriter The new log writer */ public void setAbandonedLogWriter(final PrintWriter logWriter) { if (abandonedConfig == null) { abandonedConfig = new AbandonedConfig(); } abandonedConfig.setLogWriter(logWriter); final GenericObjectPool> gop = this.connectionPool; if (gop != null) { gop.setAbandonedConfig(abandonedConfig); } } /** * If the connection pool implements {@link org.apache.tomcat.dbcp.pool2.UsageTracking UsageTracking}, configure whether * the connection pool should record a stack trace every time a method is called on a pooled connection and retain * the most recent stack trace to aid debugging of abandoned connections. * * @param usageTracking A value oftrue will enable the recording of a stack trace on every use of a
* pooled connection
*/
public void setAbandonedUsageTracking(final boolean usageTracking) {
if (abandonedConfig == null) {
abandonedConfig = new AbandonedConfig();
}
abandonedConfig.setUseUsageTracking(usageTracking);
final GenericObjectPool> gop = this.connectionPool;
if (gop != null) {
gop.setAbandonedConfig(abandonedConfig);
}
}
/**
* * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to * the underlying connection. (Default: false) *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
true by default.
*
* @param autoCommitOnReturn Whether or not connections being returned to the pool will be checked and configured
* with auto-commit.
* @since 2.6.0
*/
public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
this.autoCommitOnReturn = autoCommitOnReturn;
}
// ----------------------------------------------------- DataSource Methods
/**
* Sets the state caching flag.
*
* @param cacheState The new value for the state caching flag
*/
public void setCacheState(final boolean cacheState) {
this.cacheState = cacheState;
}
/**
* Sets the ConnectionFactory class name.
*
* @param connectionFactoryClassName A class name.
* @since 2.7.0
*/
public void setConnectionFactoryClassName(final String connectionFactoryClassName) {
if (isEmpty(connectionFactoryClassName)) {
this.connectionFactoryClassName = null;
} else {
this.connectionFactoryClassName = connectionFactoryClassName;
}
}
/**
* Sets the list of SQL statements to be executed when a physical connection is first created.
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Format of the string must be [propertyName=property;]* *
** NOTE - The "user" and "password" properties will be added explicitly, so they do not need to be included here. *
* * @param connectionProperties the connection properties used to create new connections */ public void setConnectionProperties(final String connectionProperties) { Objects.requireNonNull(connectionProperties, "connectionProperties is null"); final String[] entries = connectionProperties.split(";"); final Properties properties = new Properties(); for (final String entry : entries) { if (entry.length() > 0) { final int index = entry.indexOf('='); if (index > 0) { final String name = entry.substring(0, index); final String value = entry.substring(index + 1); properties.setProperty(name, value); } else { // no value is empty string which is how // java.util.Properties works properties.setProperty(entry, ""); } } } this.connectionProperties = properties; } /** ** Sets default auto-commit state of connections returned by this datasource. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the default catalog. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
null means that the driver default will be used.
*
* @param defaultQueryTimeoutSeconds The default query timeout in seconds.
*/
public void setDefaultQueryTimeout(final Integer defaultQueryTimeoutSeconds) {
this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
}
/**
* * Sets defaultReadonly property. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the default schema. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the default transaction isolation state for returned connections. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Overrides the defaults in {@link Utils#DISCONNECTION_SQL_CODES} (plus anything starting with * {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If this property is non-null and {@link #getFastFailValidation()} * is {@code true}, whenever connections created by this datasource generate exceptions with SQL_STATE codes in this * list, they will be marked as "fatally disconnected" and subsequent validations will fail fast (no attempt at * isValid or validation query). *
** If {@link #getFastFailValidation()} is {@code false} setting this property has no effect. *
** Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first * time one of the following methods is invoked: {@code getConnection, setLogwriter, * setLoginTimeout, getLoginTimeout, getLogWriter}. *
* * @param disconnectionSqlCodes SQL_STATE codes considered to signal fatal conditions * @since 2.1 */ public void setDisconnectionSqlCodes(final Collection
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the class loader to be used to load the JDBC driver. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the JDBC driver class name. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
true by default.
*
* @param autoCommitOnReturn Whether or not connections being returned to the pool will be checked and configured
* with auto-commit.
* @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
*/
@Deprecated
public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) {
this.autoCommitOnReturn = autoCommitOnReturn;
}
/**
* Sets the EvictionPolicy implementation to use with this connection pool.
*
* @param evictionPolicyClassName The fully qualified class name of the EvictionPolicy implementation
*/
public synchronized void setEvictionPolicyClassName(final String evictionPolicyClassName) {
if (connectionPool != null) {
connectionPool.setEvictionPolicyClassName(evictionPolicyClassName);
}
this.evictionPolicyClassName = evictionPolicyClassName;
}
/**
* @see #getFastFailValidation()
* @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;
}
/**
* * Sets the initial size of the connection pool. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Set the login timeout (in seconds) for connecting to the database. *
** Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. *
* * @param loginTimeout The new login timeout, or zero for no timeout * @throws UnsupportedOperationException If the DataSource implementation does not support the login timeout * feature. * @throws SQLException if a database access error occurs */ @Override public void setLoginTimeout(final int loginTimeout) throws SQLException { // This method isn't supported by the PoolingDataSource returned by the // createDataSource throw new UnsupportedOperationException("Not supported by BasicDataSource"); } /** ** Sets the log writer being used by this data source. *
** Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. *
* * @param logWriter The new log writer * @throws SQLException if a database access error occurs */ @Override public void setLogWriter(final PrintWriter logWriter) throws SQLException { createDataSource().setLogWriter(logWriter); this.logWriter = logWriter; } /** ** Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an * infinite lifetime. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the value of the maxOpenPreparedStatements property.
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the {@link #password}. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets whether to pool statements or not. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the timeout in seconds before an abandoned connection can be removed. *
* ** Setting this property has no effect if {@link #getRemoveAbandonedOnBorrow()} and * {@link #getRemoveAbandonedOnMaintenance()} are false. *
* * @param removeAbandonedTimeout new abandoned timeout in seconds * @see #getRemoveAbandonedTimeout() * @see #getRemoveAbandonedOnBorrow() * @see #getRemoveAbandonedOnMaintenance() */ public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) { if (abandonedConfig == null) { abandonedConfig = new AbandonedConfig(); } abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout); final GenericObjectPool> gop = this.connectionPool; if (gop != null) { gop.setAbandonedConfig(abandonedConfig); } } /** * Sets the flag that controls if a connection will be rolled back when it is returned to the pool if auto commit is * not enabled and the connection is not read only. * * @param rollbackOnReturn whether a connection will be rolled back when it is returned to the pool. */ public void setRollbackOnReturn(final boolean rollbackOnReturn) { this.rollbackOnReturn = rollbackOnReturn; } /** * Sets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the * idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. * * @param softMinEvictableIdleTimeMillis minimum amount of time a connection may sit idle in the pool before it is * eligible for eviction, assuming there are minIdle idle connections in the * pool. * @see #getSoftMinEvictableIdleTimeMillis */ public synchronized void setSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) { this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; if (connectionPool != null) { connectionPool.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis); } } /** * Sets the {@link #testOnBorrow} property. This property determines whether or not the pool will validate objects * before they are borrowed from the pool. * * @param testOnBorrow new value for testOnBorrow property */ public synchronized void setTestOnBorrow(final boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; if (connectionPool != null) { connectionPool.setTestOnBorrow(testOnBorrow); } } /** * Sets the {@link #testOnCreate} property. This property determines whether or not the pool will validate objects * immediately after they are created by the pool * * @param testOnCreate new value for testOnCreate property */ public synchronized void setTestOnCreate(final boolean testOnCreate) { this.testOnCreate = testOnCreate; if (connectionPool != null) { connectionPool.setTestOnCreate(testOnCreate); } } /** * Sets thetestOnReturn property. This property determines whether or not the pool will validate
* objects before they are returned to the pool.
*
* @param testOnReturn new value for testOnReturn property
*/
public synchronized void setTestOnReturn(final boolean testOnReturn) {
this.testOnReturn = testOnReturn;
if (connectionPool != null) {
connectionPool.setTestOnReturn(testOnReturn);
}
}
/**
* Sets the testWhileIdle property. This property determines whether or not the idle object evictor
* will validate connections.
*
* @param testWhileIdle new value for testWhileIdle property
*/
public synchronized void setTestWhileIdle(final boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
if (connectionPool != null) {
connectionPool.setTestWhileIdle(testWhileIdle);
}
}
/**
* Sets the {@link #timeBetweenEvictionRunsMillis} property.
*
* @param timeBetweenEvictionRunsMillis the new time between evictor runs
* @see #timeBetweenEvictionRunsMillis
*/
public synchronized void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
if (connectionPool != null) {
connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
}
}
/**
* * Sets the {@link #url}. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the {@link #userName}. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Sets the {@link #validationQuery}. *
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
* time one of the following methods is invoked: getConnection, setLogwriter,
* setLoginTimeout, getLoginTimeout, getLogWriter.
*