登录 DBCP

Posted

技术标签:

【中文标题】登录 DBCP【英文标题】:Logging in DBCP 【发布时间】:2011-04-05 13:30:25 【问题描述】:

我正在使用 Apache Commons DBCP。有一个任务是跟踪 DBCP 的内部行为——活动和空闲连接的数量。

我发现 DBCP 根本没有任何此类日志记录。是的,当从池中借用连接时,可以编写输出 BasicDataSource 状态的代码。但是,当连接返回或关闭时,无法跟踪 BasicDataSource 的状态,因为连接对象对池一无所知。

有什么想法吗?

【问题讨论】:

【参考方案1】:

我认为方面可能是您的困惑的解决方案。签出:

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-introduction-spring-defn http://www.ibm.com/developerworks/java/library/j-ajdt/ http://www.eclipse.org/aspectj/doc/released/progguide/index.html

基本上,您可以编写一个或两个方面来“锁定”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,以及您想要记录的内容。

附:上面的代码我没有测试过。

【讨论】:

【参考方案2】:

DBCP 的 BasicDataSource 包含一些实际创建池和池工厂的受保护方法。您可以将其子类化并覆盖这些方法以更改行为;例如,获得池工厂或用您自己的工厂替换它。拥有该池后,您就可以在代码中获取池状态。

【讨论】:

【参考方案3】:

AOP 是跟踪池中连接使用情况的方法。但是,它不是很直接。您需要执行以下操作:

    创建一个 ConnectionWrapper 类来包装(装饰器模式)Connection 并覆盖 close() 方法以额外记录连接 ID、线程 ID 和操作“关闭” 拦截数据源的getConnection()方法。 在该方法中,记录连接 ID、线程 ID 和操作“打开” 以同样的方法,装饰原始连接并返回您的 ConnectionWrapper 实例

通过此设置,您可以跟踪从/到池的连接的借用和返回。

【讨论】:

【参考方案4】:

如果您有权访问 DataSource 对象,则可以将其强制转换为 BasicDataSource 并使用 getNumActive()getNumIdle() 方法获取 maxIdlemaxActive 连接。

【讨论】:

调用 connection.close() 的地方没有对 DataSource 对象的访问。所以无法将其强制转换为 BasicDataSource 并获取 maxIdle 和 maxActive。 Connection.close() 不等于 Datasource.close() 您可以在某处保留对数据源的引用,这应该可以。

以上是关于登录 DBCP的主要内容,如果未能解决你的问题,请参考以下文章

解决MySQL8小时自动断开连接的问题(DBCP配置)

求救!!!数据库连接池出错

DBCP连接池原理分析

java.lang.AbstractMethodError:在 org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.setCharacter

Tomcat常见问题之无法加载资源工厂类dbcp

Dbcp2抛出org.apache.commons.dbcp2.LifetimeExceededException