cop和MySQL连接_数据库连接池

目前常用的数据源主要有c3p0、dbcp、proxool、druid

Spring 推荐使用dbcp;

Hibernate 推荐使用c3p0和proxool

1、 DBCP:apache

DBCP(DataBase connection pool)数据库连接池。是apache上的一个 java连接池项目,也是 tomcat使用的连接池组件。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。dbcp没有自动的去回收空闲连接的功能。

2、 C3P0:

C3P0是一个开源的jdbc连接池,它实现了数据源和jndi绑定,支持jdbc3规范和jdbc2的标准扩展。c3p0是异步操作的,缓慢的jdbc操作通过帮助进程完成。扩展这些操作可以有效的提升性能。目前使用它的开源项目有Hibernate,Spring等。c3p0有自动回收空闲连接功能。

3、 Proxool:Sourceforge

Proxool是一种Java数据库连接池技术。是sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。

综合来说,稳定性是dbcp>=c3p0>proxool

后来阿里巴巴的druid开源了,可以是前无古人后无来者,最强没有之一,十分稳定,在大并发中表现十分好

a1d49b2f3671

基本原理

pool.getConnection(),都是先从threadlocal里面拿的,如果threadlocal里面有,则用,保证线程里的多个dao操作,用的是同一个connection,以保证事务。

如果新线程,则将新的connection放在threadlocal里,再get给到线程。

重点代码

private static ThreadLocal threadLocal = new ThreadLocal();

// 获得当前连接

public Connection getCurrentConnecton(){

// 默认线程里面取

Connection conn = threadLocal.get();

if(!isValid(conn)){

conn = getConnection();

}

return conn;

}

// 获得连接

public synchronized Connection getConnection() {

Connection conn = null;

try {

// 判断是否超过最大连接数限制

if(contActive < this.dbBean.getMaxActiveConnections()){

if (freeConnection.size() > 0) {

conn = freeConnection.get(0);

if (conn != null) {

threadLocal.set(conn);

}

freeConnection.remove(0);

} else {

conn = newConnection();

}

}else{

// 继续获得连接,直到从新获得连接

wait(this.dbBean.getConnTimeOut());

conn = getConnection();

}

if (isValid(conn)) {

activeConnection.add(conn);

contActive ++;

}

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InterruptedException e) {

e.printStackTrace();

}

return conn;

}

public synchronized void releaseConn(Connection conn) throws SQLException {

if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) {

freeConnection.add(conn);

activeConnection.remove(conn);

contActive --;

threadLocal.remove();

// 唤醒所有正待等待的线程,去抢连接

notifyAll();

}

}

重理解此段话

什么是线程池,什么是ThreadLocal???

线程池,为避免不必要的创建,销毁connection而存在的,其中包括活动,等待,最小等属性,cop3,proxy连接池都可以配置这些玩意;

为什么要用ThreadLocal呢?这个和连接池无关,我认为更多的是和程序本身相关,为了更清楚的说明,举个例子

servlet中获取一个连接.首先,servlet是线程安全的吗?

class MyServlet extends HttpServlet{

private Connection conn;

}

ok,遗憾的告诉你,这个conn并不是安全的,所有请求这个servlet的连接,使用的都是一个Connection,这个就是致命的了.多个人使用同一个连接,算上延迟啥的,天知道数据会成什么样.

因此我们要保证Connection对每个请求都是唯一的.这个时候就可以用到ThreadLocal了,保证每个线程都有自己的连接.

改为 private ThreadLocal ct = new ThreadLocal();

然后从连接池获取Connection,set到ct中,再get就行了,至于得到的是哪个Connection就是连接池的问题了,你也管不到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值