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

org.apache.commons.dbcp.AbandonedObjectPool Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show 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.dbcp;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

/**
 * 

An implementation of a Jakarta-Commons ObjectPool which * tracks JDBC connections and can recover abandoned db connections. * If logAbandoned=true, a stack trace will be printed for any * abandoned db connections recovered. * * @author Glenn L. Nielsen * @version $Revision: 899987 $ $Date: 2010-01-16 11:51:16 -0500 (Sat, 16 Jan 2010) $ */ public class AbandonedObjectPool extends GenericObjectPool { /** * DBCP AbandonedConfig */ private final AbandonedConfig config; /** * A list of connections in use */ private final List trace = new ArrayList(); /** * Create an ObjectPool which tracks db connections. * * @param factory PoolableObjectFactory used to create this * @param config configuration for abandoned db connections */ public AbandonedObjectPool(PoolableObjectFactory factory, AbandonedConfig config) { super(factory); this.config = config; } /** * Get a db connection from the pool. * * If removeAbandoned=true, recovers db connections which * have been idle > removeAbandonedTimeout and * getNumActive() > getMaxActive() - 3 and * getNumIdle() < 2 * * @return Object jdbc Connection * @throws Exception if an exception occurs retrieving a * connection from the pool */ public Object borrowObject() throws Exception { if (config != null && config.getRemoveAbandoned() && (getNumIdle() < 2) && (getNumActive() > getMaxActive() - 3) ) { removeAbandoned(); } Object obj = super.borrowObject(); if (obj instanceof AbandonedTrace) { ((AbandonedTrace) obj).setStackTrace(); } if (obj != null && config != null && config.getRemoveAbandoned()) { synchronized (trace) { trace.add(obj); } } return obj; } /** * Return a db connection to the pool. * * @param obj db Connection to return * @throws Exception if an exception occurs returning the connection * to the pool */ public void returnObject(Object obj) throws Exception { if (config != null && config.getRemoveAbandoned()) { synchronized (trace) { boolean foundObject = trace.remove(obj); if (!foundObject) { return; // This connection has already been invalidated. Stop now. } } } super.returnObject(obj); } /** * Invalidates an object from the pool. * * @param obj object to be returned * @throws Exception if an exception occurs invalidating the object */ public void invalidateObject(Object obj) throws Exception { if (config != null && config.getRemoveAbandoned()) { synchronized (trace) { boolean foundObject = trace.remove(obj); if (!foundObject) { return; // This connection has already been invalidated. Stop now. } } } super.invalidateObject(obj); } /** * Recover abandoned db connections which have been idle * greater than the removeAbandonedTimeout. */ private void removeAbandoned() { // Generate a list of abandoned connections to remove long now = System.currentTimeMillis(); long timeout = now - (config.getRemoveAbandonedTimeout() * 1000); ArrayList remove = new ArrayList(); synchronized (trace) { Iterator it = trace.iterator(); while (it.hasNext()) { AbandonedTrace pc = (AbandonedTrace) it.next(); if (pc.getLastUsed() > timeout) { continue; } if (pc.getLastUsed() > 0) { remove.add(pc); } } } // Now remove the abandoned connections Iterator it = remove.iterator(); while (it.hasNext()) { AbandonedTrace pc = (AbandonedTrace) it.next(); if (config.getLogAbandoned()) { pc.printStackTrace(); } try { invalidateObject(pc); } catch (Exception e) { e.printStackTrace(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy