• 数据库连接泄漏诊断


    1 背景

    如果将mybatis guice 事务代理切面 中的endTransaction注释掉,那么将会有连接泄漏,本文是一个实践

    private void endTransactionReal() {
    //getOdsSqlSessionManager().close();
    }

    2

    2.1 连接池信息

    初始:4

    最大:10

    2.2 取得连接的过程

    org.apache.commons.dbcp.BasicDatasource.getConnection

    org.apache.commons.dbcp.BasicDatasource.createDataSource

    org.apache.commons.dbcp.PoolingDatasource.getConnection

    org.apache.commons.pool.impl.GenericObjectPool.borrowObject

    2.3 归还连接的过程

    org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close

    org.apache.commons.dbcp.PoolableConnection.close

    org.apache.commons.pool.impl.GenericObjectPool.returnObject

    3 服务器启动后

    借用一次netstat && oracle 连接检测乌龙  的方式检测初始oracle连接

    $ netstat -ano|grep ip

    TCP localinstanceip:49413 oracleip:1568 TIME_WAIT 0
    TCP localinstanceip:54128 oracleip:1567 ESTABLISHED 18612
    TCP localinstanceip:54130 oracleip:1567 ESTABLISHED 18612
    TCP localinstanceip:54132 oracleip:1568 ESTABLISHED 18612
    TCP localinstanceip:60356 oracleip:1568 ESTABLISHED 18612

    请注意,由于使用了懒加载,所以首次打开页面之前没有这些连接,后才有

    可以看到4条establish

     4 和 5 两种情况都是这个结果

    4 no endtransaction

    4.1 4次访问后(含首次激活懒加载的那个第一次)

    仍然显示4条连接

    4.2 第5次访问后

    出现5条连接,证明连接没有归还,导致连接池新开了连接

    4.3 第6-第10次访问

    断点调试调用链:

    org.apache.commons.dbcp.PoolingDatasource.getConnection

    org.apache.commons.pool.impl.GenericObjectPool.borrowObject

    commit

    end

    org.apache.commons.dbcp.PoolableConnection.close

    org.apache.commons.pool.impl.GenericObjectPool.returnObject  注意没有这两条

    结果显示10条连接

    4.4 第11次刷新页面,页面阻塞

     jstack

    可以看到有一条业务线程,(使用scef项目名ctrl F)

    "GUI-Thread-43, TaskID:825, Start Time:07-09 04:26:28" #145 prio=10 os_prio=2 tid=0x00000000277fa800 nid=0x5bec in Object.wait() [0x000000007324c000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)
    - locked <0x000000078093e458> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at com.citi.risk.core.data.db.provider.impl.LazyDataSource.getConnection(LazyDataSource.java:124)
    at org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:140)
    at org.apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:62)
    at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:315)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:75)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:61)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:303)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:154)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:102)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:82)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113)
    at sun.reflect.GeneratedMethodAccessor317.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.session.SqlSessionManager$SqlSessionInterceptor.invoke(SqlSessionManager.java:334)
    at com.sun.proxy.$Proxy179.selectList(Unknown Source)
    at org.apache.ibatis.session.SqlSessionManager.selectList(SqlSessionManager.java:190)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
    at com.sun.proxy.$Proxy325.queryUserByLikeId(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

    阻塞

    5 has endtransaction

    重复4的步骤

    5.1 第5次访问开始后若干次,仍然显示4条连接

    5.2 调用链

    org.apache.commons.dbcp.PoolingDatasource.getConnection

    org.apache.commons.pool.impl.GenericObjectPool.borrowObject

    commit

    end

    org.apache.commons.dbcp.PoolableConnection.close

    org.apache.commons.pool.impl.GenericObjectPool.returnObject

  • 相关阅读:
    android学习计划
    Android源码下载及开发环境的搭建
    I2C总线时序
    I2C原理和实例
    sql语句获取字段扩展属性
    浏览器兼容:火狐不支持webq格式图片
    js节流函数中的参数传递
    分享插件使用
    图片等比例自适应填充
    window.event在IE和Firefox的异同
  • 原文地址:https://www.cnblogs.com/silyvin/p/14991026.html
Copyright © 2020-2023  润新知