You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by le...@apache.org on 2002/01/24 03:56:47 UTC
cvs commit: jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource ResourceLimitingJdbcConnectionPool.java ResourceLimitingJdbcDataSource.java
leif 02/01/23 18:56:47
Added: src/scratchpad/org/apache/avalon/excalibur/datasource
ResourceLimitingJdbcConnectionPool.java
ResourceLimitingJdbcDataSource.java
Log:
Add new JdbcDataSource based on ResourceLimiting Pool
Revision Changes Path
1.1 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcConnectionPool.java
Index: ResourceLimitingJdbcConnectionPool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.datasource;
import org.apache.avalon.excalibur.pool.ValidatedResourceLimitingPool;
import java.sql.SQLException;
import org.apache.avalon.excalibur.datasource.JdbcConnection;
import org.apache.avalon.excalibur.pool.ObjectFactory;
import org.apache.avalon.excalibur.pool.Poolable;
/**
* A ResourceLimiting JdbcConnectionPool which allows for fine configuration of
* how the pool scales to loads.
*
* The pool supports; weak and strong pool size limits, optional blocking gets
* when connections are not available, and automatic trimming of unused
* connections.
*
* @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/01/24 02:56:47 $
* @since 4.0
*/
public class ResourceLimitingJdbcConnectionPool
extends ValidatedResourceLimitingPool
{
private boolean m_autoCommit;
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
/**
* Creates a new ResourceLimitingJdbcConnectionPool
*
* @param factory The ObjectFactory which will be used to create new connections as needed
* by the pool.
* @param max Maximum number of connections which can be stored in the pool, 0 implies
* no limit.
* @param maxStrict true if the pool should never allow more than max connections to be
* created. Will cause an exception to be thrown if more than max connections are
* requested and blocking is false.
* @param blocking true if the pool should cause a thread calling get() to block when
* connections are not currently available in the pool.
* @param blockTimeout The maximum amount of time, in milliseconds, that a call to get() will
* block before an exception is thrown. A value of 0 implies an indefinate wait.
* @param trimInterval The minimum interval with which old unused connections will be removed
* from the pool. A value of 0 will cause the pool to never trim old connections.
* @param autoCommit true if connections created by this pool should have autoCommit enabled.
*/
public ResourceLimitingJdbcConnectionPool( final ObjectFactory factory,
int max,
boolean maxStrict,
boolean blocking,
long blockTimeout,
long trimInterval,
boolean autoCommit )
{
super(factory, max, maxStrict, blocking, blockTimeout, trimInterval);
m_autoCommit = autoCommit;
}
/*---------------------------------------------------------------
* ValidatedResourceLimitingPool Methods
*-------------------------------------------------------------*/
/**
* Create a new poolable instance by by calling the newInstance method
* on the pool's ObjectFactory.
* This is the method to override when you need to enforce creational
* policies.
* This method is only called by threads that have _semaphore locked.
*/
protected Poolable newPoolable() throws Exception {
JdbcConnection conn = (JdbcConnection)super.newPoolable();
// Store a reference to this pool in the connection
conn.setPool(this);
// Set the auto commit flag for new connections.
conn.setAutoCommit(m_autoCommit);
return conn;
}
/**
* Validates the poolable before it is provided to the caller of get on this pool.
* This implementation of the validation method always returns true indicating
* that the Poolable is valid.
* The pool is not locked by the current thread when this method is called.
*
* @param poolable The Poolable to be validated
* @returns true if the Poolable is valid, false if it should be removed from the pool.
*/
protected boolean validatePoolable(Poolable poolable) {
JdbcConnection conn = (JdbcConnection)poolable;
try {
// Calling isClosed() may take time if the connection has not been
// used for a while. Is this a problem because the m_semaphore
// is currently locked? I am thinking no because isClosed() will
// return immediately when connections are being used frequently.
if (conn.isClosed()) {
getLogger().debug("JdbcConnection was closed.");
return false;
}
} catch (SQLException e) {
getLogger().debug(
"Failed to check whether JdbcConnection was closed. " + e.getMessage());
}
return true;
}
/*---------------------------------------------------------------
* Public Methods
*-------------------------------------------------------------*/
/*---------------------------------------------------------------
* Private Methods
*-------------------------------------------------------------*/
}
1.1 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/datasource/ResourceLimitingJdbcDataSource.java
Index: ResourceLimitingJdbcDataSource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.datasource;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.excalibur.datasource.JdbcConnectionFactory;
import org.apache.avalon.excalibur.datasource.NoAvailableConnectionException;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* The ResourceLimiting implementation for DataSources in Avalon. This uses the
* normal <code>java.sql.Connection</code> object and
* <code>java.sql.DriverManager</code>. The Configuration is like this:
*
* <pre>
* <jdbc>
* <pool-controller max="<i>10</i>" blocking="<i>true</i>"
* timeout="<i>-1</i>" trim-interval="<i>60000</i>"
* connection-class="<i>my.overrided.ConnectionClass</i>">
* <keep-alive>select 1</keep-alive>
* </pool-controller>
* <driver><i>com.database.jdbc.JdbcDriver</i></driver>
* <dburl><i>jdbc:driver://host/mydb</i></dburl>
* <user><i>username</i></user>
* <password><i>password</i></password>
* </jdbc>
* </pre>
*
* With the following roles declaration:
*
* <pre>
* <role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
* shorthand="datasources"
* default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector">
* <hint shorthand="jdbc"
* class="org.apache.avalon.excalibur.datasource.ResourceLimitingJdbcDataSource"/>
* </role>
* </pre>
*
* @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/01/24 02:56:47 $
* @since 4.0
*/
public class ResourceLimitingJdbcDataSource
extends AbstractLogEnabled
implements DataSourceComponent, Disposable
{
private boolean m_configured;
private boolean m_disposed;
protected ResourceLimitingJdbcConnectionPool m_pool;
/*---------------------------------------------------------------
* Constructors
*-------------------------------------------------------------*/
public ResourceLimitingJdbcDataSource() {}
/*---------------------------------------------------------------
* DataSourceComponent Methods
*-------------------------------------------------------------*/
/**
* Gets the Connection to the database
*
* @throws NoValidConnectionException when there is no valid Connection wrapper
* available in the classloader.
*
* @throws NoAvailableConnectionException when there are no more available
* Connections in the pool.
*/
public Connection getConnection()
throws SQLException
{
if ( !m_configured ) throw new IllegalStateException( "Not Configured" );
if ( m_disposed ) throw new IllegalStateException( "Already Disposed" );
Connection connection;
try
{
connection = (Connection)m_pool.get();
}
catch ( SQLException e )
{
if (getLogger().isWarnEnabled())
{
getLogger().warn("Could not return Connection", e);
}
throw e;
}
catch ( Exception e )
{
if ( getLogger().isWarnEnabled() )
{
getLogger().warn( "Could not return Connection", e );
}
throw new NoAvailableConnectionException( e.getMessage() );
}
return connection;
}
/*---------------------------------------------------------------
* DataSourceComponent (Configurable) Methods
*-------------------------------------------------------------*/
/**
* Pass the <code>Configuration</code> to the <code>Configurable</code>
* class. This method must always be called after the constructor
* and before any other method.
*
* @param configuration the class configurations.
*/
public void configure(Configuration configuration) throws ConfigurationException {
if (m_configured) throw new IllegalStateException("Already Configured");
final String driver = configuration.getChild( "driver" ).getValue( "" );
final String dburl = configuration.getChild( "dburl" ).getValue( null );
final String user = configuration.getChild( "user" ).getValue( null );
final String passwd = configuration.getChild( "password" ).getValue( null );
final Configuration controller = configuration.getChild( "pool-controller" );
String keepAlive = controller.getChild( "keep-alive" ).getValue(null);
final int max = controller.getAttributeAsInteger( "max", 3 );
final boolean blocking = controller.getAttributeAsBoolean( "blocking", true );
final long timeout = controller.getAttributeAsLong ( "timeout", -1 );
final long trimInterval = controller.getAttributeAsLong ( "trim-interval", 60000 );
final boolean oradb = controller.getAttributeAsBoolean( "oradb", false );
final boolean autoCommit = configuration.getChild("auto-commit").getValueAsBoolean(true);
final String connectionClass = controller.getAttribute( "connection-class",
"org.apache.avalon.excalibur.datasource.JdbcConnection" );
final int l_max;
// If driver is specified....
if ( ! "".equals(driver) )
{
if (getLogger().isDebugEnabled())
{
getLogger().debug("Loading new driver: " + driver);
}
try
{
Class.forName( driver, true, Thread.currentThread().getContextClassLoader() );
}
catch (ClassNotFoundException cnfe)
{
if (getLogger().isWarnEnabled())
{
getLogger().warn( "Could not load driver: " + driver, cnfe );
}
}
}
if( max < 1 )
{
if (getLogger().isWarnEnabled())
{
getLogger().warn( "Maximum number of connections specified must be at least 1." );
}
l_max = 1;
}
else
{
l_max = max;
}
if (oradb)
{
keepAlive = "SELECT 1 FROM DUAL";
if (getLogger().isWarnEnabled())
{
getLogger().warn("The oradb attribute is deprecated, please use the" +
"keep-alive element instead.");
}
}
else
{
keepAlive = "SELECT 1";
}
final JdbcConnectionFactory factory = new JdbcConnectionFactory
( dburl, user, passwd, autoCommit, keepAlive, connectionClass );
factory.enableLogging( getLogger() );
try
{
m_pool = new ResourceLimitingJdbcConnectionPool
(factory, l_max, true, blocking, timeout, trimInterval, autoCommit );
m_pool.enableLogging( getLogger() );
}
catch (Exception e)
{
if (getLogger().isDebugEnabled())
{
getLogger().debug("Error configuring ResourceLimitingJdbcDataSource", e);
}
throw new ConfigurationException("Error configuring ResourceLimitingJdbcDataSource", e);
}
m_configured = true;
}
/*---------------------------------------------------------------
* Disposable Methods
*-------------------------------------------------------------*/
/**
* The dispose operation is called at the end of a components lifecycle.
* This method will be called after Startable.stop() method (if implemented
* by component). Components use this method to release and destroy any
* resources that the Component owns.
*/
public void dispose() {
m_disposed = true;
m_pool.dispose();
m_pool = null;
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>