连接池技术解密,连接池对我们不再陌生

一、为什么我们要用连接池技术?

前面的数据库连接的建立及关闭资源的方法有些缺陷。统舱传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开、关闭该物理连接, 系统性能严重受损。

解决方案:数据库连接池(Connection Pool)。
系统初始运行时,主动建立足够的连接,组成一个池.每次应用应用程序请求数据库连接时,无需重新打开连接,而是从池中取出已有的连接,使用完后,不再关闭,而是归还。

二、连接池主要由三部分组成:连接池的建立、连接池中连接的使用管理、连接池的关闭。

三、连接池技术的核心思想

连接复用,通过建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。

1.连接池的建立
在系统初始化时,根据相应的配置创建连接并放置在连接池中,以便需要使用时能从连接池中获取,这样就可以避免连接随意的建立、关闭造成的开销。

2.连接池中连接的使用管理
      连接池管理策略是连接池机制的核心。当连接池建立后,如何对连接池中的连接进行管理,解决好连接池内连接的分配和释放,对系统的性能有很大的影响。连接的合理分配、释放可提高连接的复用,降低了系统建立新连接的开销,同时也加速了用户的访问速度。

采用的方法是一个很有名的设计模式:Reference Counting(引用记数)。该模式在复用资源方面应用的非常广泛,把该方法运用到对于连接的分配释放上,为每一个数据库连接,保留一个引用记数,用来记录该连接的使用者的个数。

(1)当客户请求数据库连接时,首先查看连接池中是否有空闲连接(指当前没有分配出去的连接)。如果存在空闲连接,则把连接分配给客户并作相应处理(即标记该连接为正在使用,引用计数加1)。如果没有空闲连接,则查看当前所开的连接数是不是已经达到maxConn(最大连接数),如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的maxWaitTime(最大等待时间)进行等待,如果等待maxWaitTime后仍没有空闲连接,就抛出无空闲连接的异常给用户。
(2)当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就删除该连接,并判断当前连接池内总的连接数是否小于minConn(最小连接数),若小于就将连接池充满;如果没超过就将该连接标记为开放状态,可供再次复用。可以看出正是这套策略保证了数据库连接的有效复用,避免频繁地建立、释放连接所带来的系统资源开销。

3.连接池的关闭
当应用程序退出时,应关闭连接池,此时应把在连接池建立时向数据库申请的连接对象统一归还给数据库(即关闭所有数据库连接),这与连接池的建立正好是一个相反过程。

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

四、连接池的实现

新建一个java工程并导入相应的包。

配置文件:

1 jdbc.driver=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/csdn
3 jdbc.user=root
4 jdbc.password=123456
5 initsize=1
6 maxactive=1
7 maxwait=5000
8 maxidle=1
9 minidle=1

dbcp的基本配置的介绍

1.initialSize :连接池启动时创建的初始化连接数量(默认值为0)
2.maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
3.maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
4.minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)
5.maxWait  :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起)

DBUtil源码如下:

  1 package com.daliu.jdbc;
  2
  3 import java.io.InputStream;
  4 import java.sql.Connection;
  5 import java.sql.SQLException;
  6 import java.util.Properties;
  7
  8 import org.apache.commons.dbcp.BasicDataSource;
  9
 10 /**
 11  * 使用连接池技术管理数据库连接
 12  */
 13 public class DBUtil {
 14
 15     //数据库连接池
 16     private static BasicDataSource dbcp;
 17
 18     //为不同线程管理连接
 19     private static ThreadLocal<Connection> tl;
 20
 21     //通过配置文件来获取数据库参数
 22     static{
 23         try{
 24             Properties prop
 25                 = new Properties();
 26
 27             InputStream is
 28                 = DBUtil.class.getClassLoader()
 29                   .getResourceAsStream(
 30                           "com/daliu/jdbc/db.properties");
 31
 32             prop.load(is);
 33             is.close();
 34
 35             //一、初始化连接池
 36             dbcp = new BasicDataSource();
 37
 38
 39             //设置驱动 (Class.forName())
 40             dbcp.setDriverClassName(prop.getProperty("jdbc.driver"));
 41             //设置url
 42             dbcp.setUrl(prop.getProperty("jdbc.url"));
 43             //设置数据库用户名
 44             dbcp.setUsername(prop.getProperty("jdbc.user"));
 45             //设置数据库密码
 46             dbcp.setPassword(prop.getProperty("jdbc.password"));
 47             //初始连接数量
 48             dbcp.setInitialSize(
 49                     Integer.parseInt(
 50                             prop.getProperty("initsize")
 51                     )
 52             );
 53             //连接池允许的最大连接数
 54             dbcp.setMaxActive(
 55                     Integer.parseInt(
 56                             prop.getProperty("maxactive")
 57                     )
 58             );
 59             //设置最大等待时间
 60             dbcp.setMaxWait(
 61                     Integer.parseInt(
 62                             prop.getProperty("maxwait")
 63                     )
 64             );
 65             //设置最小空闲数
 66             dbcp.setMinIdle(
 67                     Integer.parseInt(
 68                             prop.getProperty("minidle")
 69                     )
 70             );
 71             //设置最大空闲数
 72             dbcp.setMaxIdle(
 73                     Integer.parseInt(
 74                             prop.getProperty("maxidle")
 75                     )
 76             );
 77             //初始化线程本地
 78             tl = new ThreadLocal<Connection>();
 79         }catch(Exception e){
 80             e.printStackTrace();
 81         }
 82     }
 83
 84     /**
 85      * 获取数据库连接
 86      * @return
 87      * @throws SQLException
 88      */
 89     public static Connection getConnection() throws SQLException{
 90         /*
 91          * 通过连接池获取一个空闲连接
 92          */
 93         Connection conn
 94                     = dbcp.getConnection();
 95         tl.set(conn);
 96         return conn;
 97     }
 98
 99
100     /**
101      * 关闭数据库连接
102      */
103     public static void closeConnection(){
104         try{
105             Connection conn = tl.get();
106             if(conn != null){
107                 /*
108                  * 通过连接池获取的Connection
109                  * 的close()方法实际上并没有将
110                  * 连接关闭,而是将该链接归还。
111                  */
112                 conn.close();
113                 tl.remove();
114             }
115         }catch(Exception e){
116             e.printStackTrace();
117         }
118     }
119
120     /**
121      * 测试是否连接成功
122      * @param args
123      * @throws SQLException
124      */
125     public static void main(String[] args) throws SQLException {
126         System.out.println(getConnection());
127     }
128 }

效果如下:

时间: 2024-11-05 14:46:29

连接池技术解密,连接池对我们不再陌生的相关文章

JDBC连接池技术

一.连接池技术 (1)Java语言通过JDBC技术访问数据库的基本过程是: 1.加载数据库驱动程序: 2.通过JDBC建立数据库连接: 3.访问数据库,执行SQL语句: 4.断开数据库连接. (2)在Web应用程序开发中,使用这种模式访问数据库时,存在很多问题,为了解决这些问题,可以采用数据库连接池技术. 连接池实际上是在一个集合对象中存储一定数量的数据库连接对象.当程序需要使用数据库连接时,请求从池中获取一个空闲的连接, 程序使用完毕后再把连接放回池中重用.连接池通过重用连接的方法,减少了创建

[并发]线程池技术小白

1  线程池技术介绍 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因.比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,本文将介绍的线程池技术同样符合这一思想.

连接池技术 Connection Pooling

原创地址:http://www.cnblogs.com/jfzhu/p/3705703.html 转载请注明出处 和数据库建立一个物理连接是一个很耗时的任务,所以无论是ADO.NET还是J2EE都提供了一个连接池的技术. 一个池其实就是一个列表.在ADO.NET中,有一个Connection Manager,它对每一个connection string都管理着一个可用连接的列表,这个列表就是Connection Pool. 当第一次数据库连接被初始化时,connection manager会创建

[原创]java WEB学习笔记80:Hibernate学习之路--- hibernate配置文件:JDBC 连接属性,C3P0 数据库连接池属性等

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

SQLServer的最大连接数 超时时间已到 但是尚未从池中获取连接

很多做架构设计.程序开发.运维.技术管理的朋友可能或多或少有这样的困惑: SQLServer到底支持多少连接数的并发? SQLServer是否可以满足现有的应用吗? 现有的技术架构支持多少连接数的并发? 在硬件性能与网络性能足够理想的情况下理论上可以支持多少并发连接? 生产环境中的数据库现在的并发量是多少? 如何监控现有数据库并发的数量? 生产环境中的并发量距离理论上的最大并量发还差多少? 为此,我专门写程序做了下测试,利用循环不断的打开连接并保持连接打开不关闭,测试代码如下: using Sy

DBCP连接池与c3p0连接池

1.   DBCP连接池 2.  c3p0连接池(参见上一篇的使用步骤http://www.cnblogs.com/qlqwjy/p/7545012.html)

超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

我在玩webservice中遇到这个问题,情况是:(.net4.0)之前用的是好的,更新系统后出错.vs运行是好的,IIS运行出错..net底层抛错.换成.net2.0后完美运行.所以.net4.0出问题. ========================================================================================================= (转) 问题解决方法: 解决办法 1.在代码里面,把未关闭的连接关闭 2.扩大共

[bug]超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

引言 自己弄了一个小项目——日程管理系统,在初始化日期时,查询了数据库,每个日期就会查询一次数据库,就导致了这个问题. 问题 出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the

连接字符串中Min Pool Size的理解是错误,超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

Min Pool Size的理解是错误的 假设我们在一个ASP.NET应用程序的连接字符串中将Min Pool Size设置为30: <add name="cnblogs" connectionString="Data Source=.;Initial Catalog=cnblogs;Min Pool Size=30" providerName="System.Data.SqlClient"/> 访问一下应用程序,然后用Windows