`
Josh_Persistence
  • 浏览: 1652286 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

深入浅出数据库连接池c3p0

阅读更多

一、概述:

     数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,c3p0有两种数据源管理方式,一种是通过程序变本身来进行管理,还有一种是通过容器管理,本节讨论通过程序本身来进行管理,下一节讨论通过容器进行管理。

 

二、c3p0的三种实现方式

 

1、实现方式一:利用c3p0的API自己动手写代码,实现数据源

例如:在类路径下配置一个属性文件,config.properties,内容如下:

 

driverClass=xxx
jdbcUrl=xxx
user=xxx
password=xxx

 

 

相关的Java程序片段为:

 

Properties props = new Properties();
InputStream in = Thread.class.getResourceAsStream("config.properties");
props.load(in);
in.close();
 
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(props.getProperty("driverClass"));
cpds.setJdbcUrl(props.getProperty("jdbcUrl"));
cpds.setUser(props.getProperty("user"));
cpds.setPassword(props.getProperty("password"));

 这里只实现了一个数据源,也可以在类路径下配置一个xml文件,config.xml

 

 

<config>
	<source name="source1">
		<property name="user">root</property>
		<property name="password">xxx</property>
		<property name="url">xxx</property>
		<property name="driverClass">xxx</property>
	</source>
	
	<source name="source2">
		...
	</source>
</config>

 然后自己解析xml文件,这样可以实现多个数据源的配置

 

 

 

2、实现方式二:类路径下提供一个c3p0.properties文件,文件名必须为c3p0.properties

配置如下:

 

#驱动
c3p0.driverClass=com.mysql.jdbc.Driver
#地址
c3p0.jdbcUrl=jdbc:mysql://d-shc-00426378/tools
#用户名
c3p0.user=root
#密码
c3p0.password=root

 这里只提供了最基本的配置项,其他配置项参照 文档配置,记得是c3p0.后面加属性名就是了,最后初始化数据源的方式就是这样简单:

 

 

...
DataSource  ds = new ComboPooledDataSource();
return ds;
...

 然后就可以使用数据源了,C3P0会对c3p0.properties进行自动解析的。

 

 

 

3、实现方式二:路径下提供一个c3p0-config.xml文件

这种方式与第二种差不多,但是有更多的优点 
(1).更直观明显,很类似hibernate和spring的配置
(2).可以为多个数据源服务,提供default-config和named-config两种配置方式

 

<c3p0-config>
  <default-config>   
    <property name="user">root</property>
    <property name="password">java</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
	
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
  </default-config>
 
  <named-config name="mySource">
    <property name="user">root</property>
    <property name="password">java</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
	
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
  </named-config>
</c3p0-config>

 

...
DataSource  ds = new ComboPooledDataSource("mySource");
return ds;
...

 这样就可以使用数据源了。

 

 

三、实例,以第二种方式,即c3p0.propertis的方式为例说明

1、在classpath下创建一个文件,c3p0.properteis

 

#驱动
c3p0.driverClass=com.mysql.jdbc.Driver
#地址
c3p0.jdbcUrl=jdbc:mysql://d-shc-00426378/tools
#用户名
c3p0.user=root
#密码
c3p0.password=root
#-------------------------------
#连接池初始化时创建的连接数
c3p0.initialPoolSize=3
#连接池保持的最小连接数
c3p0.minPoolSize=3
#连接池在无空闲连接可用时一次性创建的新数据库连接数,default:3
c3p0.acquireIncrement=3
#连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放,所以这个值有可能会设计地很大,default : 15
c3p0.maxPoolSize=15
#连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接,单位秒
c3p0.maxIdleTime=100
#连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功
c3p0.acquireRetryAttempts=30
#连接池在获得新连接时的间隔时间
c3p0.acquireRetryDelay=1000

 

 

2、封装一个C3p0ConnectionPool用来创建数据库连接

 

package com.wsheng.aggregator.c3p0;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * @author Josh Wang(Sheng)
 * 
 * @email  josh_wang23@hotmail.com
 * 
 */
public class C3p0ConnectionPool {
	
	private DataSource ds;
	
	private static C3p0ConnectionPool pool;
	
	private C3p0ConnectionPool() {
		ds = new ComboPooledDataSource();
	}
	
	// 加上synchronized就是典型的同步模式
	public static /*synchronized*/ final C3p0ConnectionPool getInstance() {
		if (pool == null) {
			try {
				pool = new C3p0ConnectionPool();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return pool;
	}
	
	// synchronized保证每个pool线程请求返回的都是不同的Connection
	public synchronized final Connection getConnection() {
		try {
			Connection connection = ds.getConnection();
			// 1)将配置文件中的c3p0.initialPoolSize,c3p0.minPoolSize,c3p0.maxPoolSize都改为1,然后执行查看结果
			// 2)将配置文件中的c3p0.initialPoolSize,c3p0.minPoolSize,c3p0.maxPoolSize都改为较小的值,加大线程数,然后执行查看结果
			System.out.println(" **** current connection number: " + ((ComboPooledDataSource)ds).getNumConnections() 
					+ " busy connection number: " + ((ComboPooledDataSource)ds).getNumBusyConnections() 
					+ " Idle connection nmuber: " + ((ComboPooledDataSource)ds).getNumIdleConnections());
			return connection;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	

}

 

 

3、创建模拟用户发起数据库连接的Thread类

 

package com.wsheng.aggregator.c3p0;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * @author Josh Wang(Sheng)
 * 
 * @email josh_wang23@hotmail.com
 * 
 */
public class C3p0PoolThread extends Thread {

	@Override
	public void run() {
		C3p0ConnectionPool pool = C3p0ConnectionPool.getInstance();
		Connection connection = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		
		try {
			connection = pool.getConnection();
			stmt = connection.prepareStatement("select sysdate() as nowtime from dual");
			rs = stmt.executeQuery();
			while (rs.next()) {
				System.out.println(Thread.currentThread().getId() + "---------------开始" + rs.getString("nowtime"));  
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				stmt.close();
				connection.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		System.out.println(Thread.currentThread().getId() + "--------结束");  
		
	}

	
}

 

 

4、Main类

 

package com.wsheng.aggregator.c3p0;

/**
 * @author Josh Wang(Sheng)
 * 
 * @email  josh_wang23@hotmail.com
 * 
 */
public class C3p0Main {
	
	public static void main(String[] args) {
		System.out.println("数据库连接池模拟开始"); 
        C3p0PoolThread[] threads = new C3p0PoolThread[100];  
        
        for (int i = 0; i < threads.length;i++) {  
            threads[i] = new C3p0PoolThread();  
        }  
        
        for (int i= 0;i < threads.length; i++) {  
            threads[i].start();  
        }  
	}

}

 在C3p0Main.java中可以增加线程数,也可以再c3p0.properties中减少c3p0.maxPoolSize, c3p0.minPoolSize, c3p0.initialPoolSize等的值来查看执行结果。

 

四、常用配置参数的说明:

1.最常用配置

 

initialPoolSize: 连接池初始化时创建的连接数,default : 3(建议使用)

minPoolSize: 连接池保持的最小连接数,default : 3(建议使用)

maxPoolSize: 连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放,所以这个值有可能会设计地很大,default : 15(建议使用)

acquireIncrement:连接池在无空闲连接可用时一次性创建的新数据库连接数,default : 3(建议使用)

 

 

2.管理连接池的大小和连接的生存时间

 

maxConnectionAge:配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待它close再断开。配置为0的时候则不会对连接的生存时间进行限制。default : 0 单位 s(不建议使用)

 

maxIdleTime:连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接。如果为0,则永远不会断开连接,即回收此连接。default : 0 单位 s(建议使用)

 

maxIdleTimeExcessConnections:这个配置主要是为了快速减轻连接池的负载,比如连接池中连接数因为某次数据访问高峰导致创建了很多数据连接,但是后面的时间段需要的数据库连接数很少,需要快速释放,必须小于maxIdleTime。其实这个没必要配置,maxIdleTime已经配置了。default : 0 单位 s(不建议使用)

 

3.配置连接测试:

 

automaticTestTable:配置一个表名,连接池根据这个表名用自己的测试sql语句在这个空表上测试数据库连接,这个表只能由c3p0来使用,用户不能操作。default : null(不建议使用)

 

preferredTestQuery:与上面的automaticTestTable二者只能选一。自己实现一条SQL检测语句。default : null(建议使用)

 

idleConnectionTestPeriod:用来配置测试空闲连接的间隔时间。测试方式还是上面的两种之一,可以用来解决MySQL8小时断开连接的问题。因为它保证连接池会每隔一定时间对空闲连接进行一次测试,从而保证有效的空闲连接能每隔一定时间访问一次数据库,将于MySQL8小时无会话的状态打破。为0则不测试。default : 0(建议使用)

 

testConnectionOnCheckin:如果为true,则在close的时候测试连接的有效性。default : false(不建议使用)

 

testConnectionOnCheckout:性能消耗大。如果为true,在每次getConnection的时候都会测试,为了提高性能,尽量不要用。default : false(不建议使用)

 

4.配置PreparedStatement缓存:

maxStatements:连接池为数据源缓存的PreparedStatement的总数。由于PreparedStatement属于单个Connection,所以这个数量应该根据应用中平均连接数乘以每个连接的平均PreparedStatement来计算。同时maxStatementsPerConnection的配置无效。default : 0(不建议使用)

 

maxStatementsPerConnection:连接池为数据源单个Connection缓存的PreparedStatement数,这个配置比maxStatements更有意义,因为它缓存的服务对象是单个数据连接,如果设置的好,肯定是可以提高性能的。为0的时候不缓存。default : 0(看情况而论)

 

5.重连相关配置 

acquireRetryAttempts:连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功。default : 30(建议使用)

 

acquireRetryDelay:连接池在获得新连接时的间隔时间。default : 1000 单位ms(建议使用)

 

breakAfterAcquireFailure:如果为true,则当连接获取失败时自动关闭数据源,除非重新启动应用程序。所以一般不用。default : false(不建议使用)

 

checkoutTimeout:配置当连接池所有连接用完时应用程序getConnection的等待时间。为0则无限等待直至有其他连接释放或者创建新的连接,不为0则当时间到的时候如果仍没有获得连接,则会抛出SQLException。其实就是acquireRetryAttempts*acquireRetryDelay。default : 0(与上面两个,有重复,选择其中两个都行)

 

6.定制管理Connection的生命周期

connectionCustomizerClassName:用来定制Connection的管理,比如在Connection acquire 的时候设定Connection的隔离级别,或者在Connection丢弃的时候进行资源关闭,

就可以通过继承一个AbstractConnectionCustomizer来实现相关方法,配置的时候使用全类名。有点类似监听器的作用。default : null(不建议使用)

 

7.配置未提交的事务处理 

autoCommitOnClose:连接池在回收数据库连接时是否自动提交事务。如果为false,则会回滚未提交的事务,如果为true,则会自动提交事务。default : false(不建议使用)

forceIgnoreUnresolvedTransactions:这个配置强烈不建议为true。default : false(不建议使用)

一般来说事务当然由自己关闭了,为什么要让连接池来处理这种不细心问题呢?

 

8.配置debug和回收Connection

unreturnedConnectionTimeout:为0的时候要求所有的Connection在应用程序中必须关闭。如果不为0,则强制在设定的时间到达后回收Connection,所以必须小心设置,保证在回收之前所有数据库操作都能够完成。这种限制减少Connection未关闭情况的不是很适用。建议手动关闭。default : 0 单位 s(不建议使用)

 

debugUnreturnedConnectionStackTraces:如果为true并且unreturnedConnectionTimeout设为大于0的值,当所有被getConnection出去的连接unreturnedConnectionTimeout时间到的时候,就会打印出堆栈信息。只能在debug模式下适用,因为打印堆栈信息会减慢getConnection的速度default : false(不建议使用)

 

其他配置项:因为有些配置项几乎没有自己配置的必要,使用默认值就好,所以没有再写出来。

 

3
2
分享到:
评论

相关推荐

    数据库连接池部分讲解1.zip

    这个视频教程可能深入浅出地解释了这些概念,并通过实际示例演示了如何配置和使用数据库连接池,对于学习和理解数据库连接池的工作原理及应用具有很大帮助。通过学习这些知识,开发者可以更好地优化数据库应用的性能...

    深入浅出mybatis系列

    `&lt;transactionManager type="JDBC"&gt;`表明使用JDBC来管理事务,`&lt;dataSource type="POOLED"&gt;`则指定了使用连接池(例如C3P0或HikariCP),提高数据库连接的复用性。 在数据库配置方面,通常会有一个外部的`dbConfig....

    深入浅出JBPM

    包括配置框架关系、管理事件、注入Hibernate session、资源注入等高级API使用,以及DbPersistenceServiceFactory、Hibernate会话工厂、C3P0连接池和Ehcache缓存提供者等配置项,支持多种数据库兼容性和事务管理策略...

    2013版Struts2.X深入浅出 牛牧 STM_SH_V3

    4. 数据库连接池的配置和使用,如C3P0或DBCP。 5. SQL查询的编写和优化,包括HQL的使用。 6. MVC设计模式在实际项目中的应用。 7. 项目的构建和部署过程,包括Eclipse或IntelliJ IDEA等IDE的使用。 通过亲自运行此...

    JDBC API数据库编程实作教材

    - 连接池如C3P0、HikariCP、Apache DBCP等,可管理和复用数据库连接,提高系统性能。 - 配置连接池参数,如最大连接数、超时时间、验证查询等。 9. **JDBC与ORM框架** - ORM(对象关系映射)框架如Hibernate、...

    JSP数据库编程指南.rar

    在数据库连接池的概念上,书里可能会提及C3P0、Apache DBCP等工具,它们能有效地管理数据库连接,提高应用性能并减少资源浪费。理解并正确配置这些连接池是大型Web应用不可或缺的一部分。 接下来,书中会介绍如何在...

    Java 数据库编程宝典

    为提高系统性能,使用连接池(如C3P0, HikariCP, DBCP)管理数据库连接。它们提供连接的复用,减少创建和销毁连接的开销。 7.JPA(Java Persistence API)与Hibernate: JPA是Java官方的ORM(Object-Relational ...

    传智播客jdbc详解ppt(方立勋老师的)

    方立勋老师的PPT可能还会涉及**JDBC连接池**的概念,如C3P0、DBCP、HikariCP等,它们用于管理和复用数据库连接,提高系统性能。连接池会预先创建一定数量的连接,当需要时直接分配,使用完毕后归还,避免频繁创建和...

    HibernateORM

    7. 数据库连接池:了解如何集成和配置数据库连接池,如C3P0、DBCP或HikariCP,以优化数据库连接的管理和复用。 8.性能优化:包括延迟加载(Lazy Loading)、批处理(Batch Processing)、缓存策略调整等方法,以...

    MySQL and Java Developers Guide

    - **C3P0**: 开源连接池组件。 - **HikariCP**: 性能优秀的连接池实现。 ##### 5. 异常处理与事务管理 - **异常处理**: - 使用try-catch结构处理可能出现的SQLException。 - 关闭资源: 确保在finally块中释放...

    JAVA-JDBC经典教程

    3. **数据库连接池**:介绍如何使用C3P0、Apache DBCP、HikariCP等数据库连接池技术,提高应用程序性能和资源利用率。 4. **事务管理**:讲解JDBC中的事务概念,包括ACID属性、手动提交和自动提交、事务隔离级别等...

    JDBC API Tutorial and Reference 3rd Edition

    10. **JDBC连接池**: 为了提高性能和资源管理,开发人员通常使用连接池来复用数据库连接,如C3P0、HikariCP和Apache DBCP等。 此外,JDBC 4.0引入了自动注册驱动和Java类型与SQL类型之间的自动映射,简化了代码。而...

    JAVA-connect-to-the-database.zip_connect

    在实际应用中,通常会使用连接池(如Apache Commons DBCP、C3P0或HikariCP)来管理数据库连接,提高性能并减少资源浪费。 总的来说,学习Java连接数据库是一个重要的起点,它开启了Java开发者与数据存储交互的大门...

    Java中间件实践

    此外,数据库连接池如HikariCP和C3P0能有效地管理和复用数据库连接,提升系统性能。 在处理并发和异步任务时,线程池(如Java内置的ExecutorService)和消息队列(如RabbitMQ或ActiveMQ)是常用工具。线程池可以...

    simple-hibernate:独立应用程序的简单Hibernate配置

    《深入浅出:独立应用程序中的简单Hibernate配置》 在Java开发中,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本文将详细介绍如何在独立应用程序中进行简单的Hibernate配置,以便...

    孙卫勤 Java web 与tomcat 编程第二版 源码

    孙卫勤是Java领域的知名专家,他的书籍深入浅出,适合初学者和有经验的开发者。通过分析这些源码,我们可以了解Java Web应用的开发流程,以及如何有效地利用Tomcat作为应用服务器。 Java Web开发涵盖了多个技术领域...

    Java应用开发指南配套PPT

    - 数据库连接池:C3P0, DBCP, HikariCP - SQL语句执行与结果集处理 - DAO设计模式 10. **Spring框架** - Spring核心:依赖注入(DI)、AOP(面向切面编程) - Spring MVC:Web应用开发 - Spring Boot:快速...

    javaEE ppt 教程

    此外,还将涉及连接池的概念,如C3P0和Apache DBCP,它们能提高数据库操作的效率和资源管理。 进一步,JavaEE教程还会涉及到Entity Beans和Java Persistence API (JPA),这是处理对象关系映射(ORM)的标准方式。...

Global site tag (gtag.js) - Google Analytics