c3p0连接池啊就不多说了。有一个问题吧就是连接使用完毕后要怎么放回连接池,供下次继续使用。
答案是:

conn.close();// 放回

可以将连接放回。但在实际应用中有时候发现调用这个方法以后连接还是在使用中,没有被返还。
于是各种百度、google。
发现获取连接有两种方法。
第一种是

ComboPooledDataSource cpds = new ComboPooledDataSource();
conn = cpds.getConnection();

第二种是

conn = cpds.getConnectionPoolDataSource().getPooledConnection().getConnection();

先来说第一种,在使用c3p0时连接的获取和放回都和我们使用jdbc的时候是一样的,但是效果却不同,比如jdbc是真实的关闭掉了连接,而c3p0却是将连接放回了连接池。
那么它是如何做到的呢?
答案是使用代理,当咱们调用连接的close方法的时候其实被c3p0的代理方法C3P0ProxyConnection代理了,而C3P0ProxyConnection其实只是一个接口,在c3p0中它只有暂时一个实现NewProxyConnection,它同时实现了Connection和 C3P0ProxyConnection。然后它的结构

下面还有很多方法我就不都截出来了,但是看到这相信大伙都有一种恍然大悟的感觉了。
接着往上讲,当使用第一种方法获取连接:

  //implementation of javax.sql.DataSourcepublic Connection getConnection() throws SQLException{PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();return pc.getConnection();}

从池管理那里获取连接池,然后检出池内的连接,看起来很简单,但是随着一层一层剥开c3p0的代码我们可以发现最终在BasicResourcePool有些很有趣的东西,这使c3p0更和蔼可亲(其实是比较好理解了)。

   /*  keys are all valid, managed resources, value is a PunchCard */ HashMap  managed = new HashMap();/* all valid, managed resources currently available for checkout */LinkedList unused = new LinkedList();/* resources which have been invalidated somehow, but which are *//* still checked out and in use.                                */HashSet  excluded = new HashSet();

他们分别是:管理着的连接,未使用的连接,失效的资源(但他们是任然检出并正在使用中的连接)。
看到这个不得不提起我们用来监听c3p0状态时使用的方法,

log.debug("正忙着 busy:{}", cpds.getNumBusyConnections());
log.debug("总共的 all:{}", cpds.getNumConnectionsDefaultUser());
log.debug("清闲的 Leisurely:{}", cpds.getNumIdleConnectionsDefaultUser());
log.debug("孤立连接 Excluded:{}", cpds.getNumUnclosedOrphanedConnectionsDefaultUser());

调用这些方法的时候c3p0又是怎么返回这些状态的呢,相信有的小伙伴心里已经有了答案。

  public synchronized int getAvailableCount(){ return unused.size(); }public synchronized int getExcludedCount(){ return excluded.size(); }public synchronized int getAwaitingCheckinCount(){ return managed.size() - unused.size() + excluded.size(); }public synchronized int getAwaitingCheckinNotExcludedCount(){ return managed.size() - unused.size(); }

所以说在c3p0管理的最后其实是通过一个个集合和map来对使用的未使用的集合进行管理,当使用连接不够但managed.size()<定义的最大连接数时,会生成新的连接并放入unused中,当managed.size()>定义的最大连接数时会等待配置的timeout时间,如果超出这个时间还是没有空闲的连接则会抛出异常。
在获取连接时会从unused中拿出连接并对该连接进行标记并添加监听ConnectionEventListener。
最后放回连接调用conn.close()方法其实使用的是NewProxyConnection的close方法,首先对连接进行清理,清空如ResultSets和Statements,reset一些属性,清除监听ConnectionEventListener,然后将连接归还到unused中。
有兴趣的朋友可以仔细去阅读c3p0的源码,其中这些取出归还操作其实包含很多同步和异步操作、异常的处理方式也很有意思,很多东西可以学习。
然而上面的那两种方法,第一种是通过BasicResourcePool来操作,第二种是通过WrapperConnectionPoolDataSource 直接从数据源获取连接,然后通过获取到的连接创建NewPooledConnection来获取连接的,注意到在使用时没有将他放入unused,所以在管理它,比如获取连接池使用情况的时候是获取不到的。

ps:此篇文章为更新文章,因为最开始一直在这里提倡第二种方法表示抱歉。在真正了解到他们两之后才明白过来。当然这篇文章还不算很深入,后续如果有机会再对c3p0连接这块进行研究的话会再更新文章的。谢谢看这篇文章的人,希望能有所收获。

c3p0连接池使用完毕后连接返还相关推荐

  1. HikariCP连接池8小时后只有一个连接或session问题

    项目中的一个批处理程序,需要长时间与数据库保持连接,属于典型的"写多读少"场景.监控的结果发现程序前8小时性能很好,之后就开始衰减. 用 show full process lis ...

  2. 连接池超时配置_HttpClient连接池的一些思考

    前言 使用apache的httpclient进行http的交互处理已经很长时间了,而httpclient实例则使用了http连接池,想必大家也没有关心过连接池的管理.事实上,通过分析httpclien ...

  3. 连接池原理介绍+常用连接池介绍

    下面以访问MySQL为例,执行一个SQL命令,如果不使用连接池,需要经过哪些流程. 不使用数据库连接池的步骤: TCP建立连接的三次握手 MySQL认证的三次握手 真正的SQL执行 MySQL的关闭 ...

  4. druid连接池mysql5.7_MySQL Druid连接池,Apache的DbUtils使用

    一.Druid连接池在程序初始化时,预先创建指定数量的数据库连接对象存储在池中. 当需要连接数据库时,从连接池中取出现有连接: 使用完毕后, 也不会进行关闭,而是放回池中,实现复用,节省资源. 1.1 ...

  5. JDBC实例--JDBC连接池技术解密,连接池对我们不再陌生

    一.为什么我们要用连接池技术? 前面的数据库连接的建立及关闭资源的方法有些缺陷.统舱传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开.关闭该物理连接, 系统性能严重受损. 解 ...

  6. ado.net mysql 连接池_ADO.NET数据连接池

    [IT168 技术文档]21世纪什么最贵?数据库连接.对于以数据库做数据存储基石的应用系统来说,数据库连接是整个系统中最珍贵的资源之一.数据库连接池是为了更有效地利用数据库连接的最重要措施.它对于一个 ...

  7. 04 | 连接池:别让连接池帮了倒忙

    04 | 连接池:别让连接池帮了倒忙 连接池一般对外提供获得连接.归还连接的接口给客户端使用,并暴露最小空闲连接数.最大连接数等可配置参数,在内部则实现连接建立.连接心跳保持.连接管理.空闲连接回收. ...

  8. 连接池:别让连接池帮了倒忙

    今天,我再与你说说另一种很重要的池化技术,即连接池. 我先和你说说连接池的结构.连接池一般对外提供获得连接.归还连接的接口给客户端使用,并暴露最小空闲连接数.最大连接数等可配置参数,在内部则实现连接建 ...

  9. springboot2整合redis使用lettuce连接池(解决lettuce连接池无效问题)

    lettuce客户端 Lettuce 和 Jedis 的都是连接Redis Server的客户端程序.Jedis在实现上是直连redis server,多线程环境下非线程安全(即多个线程对一个连接实例 ...

最新文章

  1. mysql中的多行查询结果合并成一个
  2. 人工智能和机器人将成为数据中心最佳“伴侣”
  3. 成功的自动化测试实施的5大支柱(译)
  4. 吸引纠缠的双白矮星和迭代收敛的神经网络
  5. android打印html页面,Android打印HTML文档
  6. MYSQL:Error Code: 1786 Statement violates GTID consistency: CREATE TABLE ... SELECT.
  7. OPPO Find X,一款(可能)被全面屏“耽搁”了的AI手机
  8. android学习中常见问题集锦
  9. s和jquery设置disabled属性为true使按钮失效
  10. github使用命令
  11. php 盒子边距,CSS 盒子模型外边距
  12. directadmin(DirectAdmin Extended)
  13. 计算机程序中的自省程序(反射程序)(introspective program)是什么?(introspectable、introspection)
  14. 【听书笔记-0515】-《清单革命》
  15. 计算机网络安全(三)
  16. 504 gateway timeout解决方法
  17. 笔记本外接显示屏模糊解决办法,调缩放比没用?
  18. 使用AS3.0开发FC超级马里奥
  19. 华为HCIP-DATACOM题库解析271-300(821)
  20. 用电脑怎么制作GIF

热门文章

  1. 使用php生成二维码
  2. [Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)
  3. 分享一个适合做年终总结软件
  4. python数星星_最好的朋友:C++11 移动语义和 Pimpl 手法
  5. 在android上启动分屏的方法
  6. 智慧工厂:EasyNVR如何让工厂实现现代化与智能化视频监控与管理?
  7. 算法竞赛入门经典的java实现之QWERTYU-Demo23.java
  8. Scrapy Spider中间件,你学会了吗?本篇博客有一案例
  9. 某网站高度加密混淆的javascript的分析 1
  10. ESP8266桌面时钟总结