All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.dbcp2.datasources.SharedPoolDataSource Maven / Gradle / Ivy

The newest version!
/*
 * 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.commons.dbcp2.datasources;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.sql.ConnectionPoolDataSource;

import org.apache.commons.pool2.KeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;

/**
 * 

* A pooling {@code DataSource} appropriate for deployment within J2EE environment. There are many configuration * options, most of which are defined in the parent class. All users (based on user name) share a single maximum number * of Connections in this data source. *

* *

* User passwords can be changed without re-initializing the data source. When a * {@code getConnection(user name, password)} request is processed with a password that is different from those * used to create connections in the pool associated with {@code user name}, an attempt is made to create a new * connection using the supplied password and if this succeeds, idle connections created using the old password are * destroyed and new connections are created using the new password. *

* * @since 2.0 */ public class SharedPoolDataSource extends InstanceKeyDataSource { private static final long serialVersionUID = -1458539734480586454L; // Pool properties private int maxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL; private transient KeyedObjectPool pool; private transient KeyedCPDSConnectionFactory factory; /** * Default no-argument constructor for Serialization */ public SharedPoolDataSource() { // empty. } /** * Closes pool being maintained by this data source. */ @Override public void close() throws SQLException { if (pool != null) { pool.close(); } InstanceKeyDataSourceFactory.removeInstance(getInstanceKey()); } @Override protected PooledConnectionManager getConnectionManager(final UserPassKey userPassKey) { return factory; } /** * Gets {@link GenericKeyedObjectPool#getMaxTotal()} for this pool. * * @return {@link GenericKeyedObjectPool#getMaxTotal()} for this pool. */ public int getMaxTotal() { return this.maxTotal; } // ---------------------------------------------------------------------- // Instrumentation Methods /** * Gets the number of active connections in the pool. * * @return The number of active connections in the pool. */ public int getNumActive() { return pool == null ? 0 : pool.getNumActive(); } /** * Gets the number of idle connections in the pool. * * @return The number of idle connections in the pool. */ public int getNumIdle() { return pool == null ? 0 : pool.getNumIdle(); } @Override protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String userPassword) throws SQLException { synchronized (this) { if (pool == null) { try { registerPool(userName, userPassword); } catch (final NamingException e) { throw new SQLException("registerPool failed", e); } } } try { return pool.borrowObject(new UserPassKey(userName, userPassword)); } catch (final Exception e) { throw new SQLException("Could not retrieve connection info from pool", e); } } /** * Creates a new {@link Reference} to a {@link SharedPoolDataSource}. */ @Override public Reference getReference() throws NamingException { final Reference ref = new Reference(getClass().getName(), SharedPoolDataSourceFactory.class.getName(), null); ref.add(new StringRefAddr("instanceKey", getInstanceKey())); return ref; } /** * Supports Serialization interface. * * @param in * a {@link java.io.ObjectInputStream} value * @throws IOException * if an error occurs * @throws ClassNotFoundException * if an error occurs */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { try { in.defaultReadObject(); final SharedPoolDataSource oldDS = (SharedPoolDataSource) new SharedPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null); this.pool = oldDS.pool; } catch (final NamingException e) { throw new IOException("NamingException: " + e); } } private void registerPool(final String userName, final String password) throws NamingException, SQLException { final ConnectionPoolDataSource cpds = testCPDS(userName, password); // Create an object pool to contain our PooledConnections factory = new KeyedCPDSConnectionFactory(cpds, getValidationQuery(), getValidationQueryTimeoutDuration(), isRollbackAfterValidation()); factory.setMaxConn(getMaxConnDuration()); final GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig<>(); config.setBlockWhenExhausted(getDefaultBlockWhenExhausted()); config.setEvictionPolicyClassName(getDefaultEvictionPolicyClassName()); config.setLifo(getDefaultLifo()); config.setMaxIdlePerKey(getDefaultMaxIdle()); config.setMaxTotal(getMaxTotal()); config.setMaxTotalPerKey(getDefaultMaxTotal()); config.setMaxWait(getDefaultMaxWait()); config.setMinEvictableIdleDuration(getDefaultMinEvictableIdleDuration()); config.setMinIdlePerKey(getDefaultMinIdle()); config.setNumTestsPerEvictionRun(getDefaultNumTestsPerEvictionRun()); config.setSoftMinEvictableIdleDuration(getDefaultSoftMinEvictableIdleDuration()); config.setTestOnCreate(getDefaultTestOnCreate()); config.setTestOnBorrow(getDefaultTestOnBorrow()); config.setTestOnReturn(getDefaultTestOnReturn()); config.setTestWhileIdle(getDefaultTestWhileIdle()); config.setTimeBetweenEvictionRuns(getDefaultDurationBetweenEvictionRuns()); final KeyedObjectPool tmpPool = new GenericKeyedObjectPool<>(factory, config); factory.setPool(tmpPool); pool = tmpPool; } /** * Sets {@link GenericKeyedObjectPool#getMaxTotal()} for this pool. * * @param maxTotal * {@link GenericKeyedObjectPool#getMaxTotal()} for this pool. */ public void setMaxTotal(final int maxTotal) { assertInitializationAllowed(); this.maxTotal = maxTotal; } @Override protected void setupDefaults(final Connection connection, final String userName) throws SQLException { final Boolean defaultAutoCommit = isDefaultAutoCommit(); if (defaultAutoCommit != null && connection.getAutoCommit() != defaultAutoCommit) { connection.setAutoCommit(defaultAutoCommit); } final int defaultTransactionIsolation = getDefaultTransactionIsolation(); if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) { connection.setTransactionIsolation(defaultTransactionIsolation); } final Boolean defaultReadOnly = isDefaultReadOnly(); if (defaultReadOnly != null && connection.isReadOnly() != defaultReadOnly) { connection.setReadOnly(defaultReadOnly); } } @Override protected void toStringFields(final StringBuilder builder) { super.toStringFields(builder); builder.append(", maxTotal="); builder.append(maxTotal); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy