Вход в DBCP - программирование
Подтвердить что ты не робот

Вход в DBCP

Я использую DBCP Apache. Существует задача отслеживать внутреннее поведение DBCP - количество активных и незанятых соединений.

Я узнал, что DBCP вообще не имеет такого ведения. Да, tt можно написать код, который выводит статус источника BasicDataSource, когда соединение заимствовано из пула. Однако нет способа отслеживать состояние источника BasicDataSource при возврате или закрытии соединения, поскольку объект подключения ничего не знает о пуле.

Любые идеи?

4b9b3361

Ответ 1

Я думаю, что аспекты могут быть решением вашего quandry. Выезд:

В принципе, вы можете написать один или два аспекта, которые будут "защелкиваться" на выполнении некоторых методов внутри DBCP.

Что-то вроде:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {

  @Around("org.apache.commons.dbcp.PoolingDataSource.getConnection()")
  public Object doBasicPStuff(ProceedingJoinPoint pjp) throws Throwable {
    // write code to do what you want
    final PoolingDataSource ds = (PoolingDataSource) pjp.getThis();
    // log whatever you want

    // let it finish
    Object retVal = pjp.proceed();
    // stop stopwatch
    return retVal;
  }

}

Это всего лишь крошечный пример. Аспекты действительно мощные, и есть множество разных способов сделать то, что вы хотите. Код зависит от того, используете ли вы Spring или нет, и что именно вы хотите зарегистрировать.

P.S. Я не тестировал вышеуказанный код.

Ответ 2

DBCP BasicDataSource содержит несколько защищенных методов, которые фактически создают пулы и пул-заводы. Вы можете подклассифицировать его и переопределить эти методы для изменения поведения; например, чтобы удержать пул factory или заменить его своим. После того, как у вас есть этот пул, вы можете войти в состояние пула в своем коде.

Ответ 3

AOP - это способ отслеживания использования соединения с пулом. Однако, это не очень прямолинейно. Вам необходимо сделать следующее:

  • Создайте класс ConnectionWrapper, который обертывает (шаблон Decorator). Соединение и переопределите метод close(), чтобы дополнительно зарегистрировать идентификатор соединения, идентификатор потока и действие "закрыть"
  • Перехват метода getConnection() источника данных.
  • В этом методе зарегистрируйте идентификатор соединения, идентификатор потока и действие "открыть"
  • В том же методе декорируйте исходное соединение и верните экземпляр ConnectionWrapper

С помощью этой настройки вы можете отслеживать как заимствование, так и возврат соединения из/в пул.

Ответ 4

Если у вас есть доступ к объекту DataSource, вы можете передать его в BasicDataSource и получить соединения maxIdle и maxActive, используя методы getNumActive() и getNumIdle().