jdbc作为一种数据库访问技术,具有简单易用的优点。但使用这种模式进行web应用
程序开发,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
数据库连接池(connection pool)的工作原理
1、基本概念及原理
由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,
对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。连接池的基本工作原理见下图2。
public synchronized connection getconnection()
连接池的实现
1、连接池模型
本文讨论的连接池包括一个连接池类(dbconnectionpool)和一个连接池管理类(dbconnetionpoolmanager)。连接池类是对某一数据库所有连接的“缓冲池”,主要实现以下功能:①从连接池获取或创建可用连接;②使用完毕之后,把连接返还给连接池;③在系统关闭前,断开所有连接并释放连接占用的系统资源;④还能够处理无效连接(原来登记为可用的连接,由于某种原因不再可用,如超时,通讯问题),并能够限制连接池中的连接总数不低于某个预定值和不超过某个预定值。
连接池管理类是连接池类的外覆类(wrapper),符合单例模式,即系统中只能有一个连接池管理类的实例。其主要用于对多个连接池对象的管理,具有以下功能:①装载并注册特定数据库的jdbc驱动程序;②根据属性文件给定的信息,创建连接池对象;③为方便管理多个连接池对象,为每一个连接池对象取一个名字,实现连接池名字与其实例之间的映射;④跟踪客户使用连接情况,以便需要是关闭连接释放资源。连接池管理类的引入主要是为了方便对多个连接池的使用和管理,如系统需要连接不同的数据库,或连接相同的数据库但由于安全性问题,需要不同的用户使用不同的名称和密码。
2、连接池实现
下面给出连接池类和连接池管理类的主要属性及所要实现的基本接口:
public class dbconnectionpool implements timerlistener{
private int checkedout;//已被分配出去的连接数
private arraylist freeconnections = new arraylist();//容器,空闲池,根据//创建时间顺序存放已创建但尚未分配出去的连接
private int minconn;//连接池里连接的最小数量
private int maxconn;//连接池里允许存在的最大连接数
private string name;//为这个连接池取个名字,方便管理
private string password;//连接数据库时需要的密码
private string url;//所要创建连接的数据库的地址
private string user;//连接数据库时需要的用户名
public timer timer;//定时器
public dbconnectionpool(string name, string url, string user, string
password, int maxconn)//公开的构造函数
public synchronized void freeconnection(connection con) //使用完毕之后,//把连接返还给空闲池
public synchronized connection getconnection(long timeout)//得到一个连接,//timeout是等待时间
public synchronized void release()//断开所有连接,释放占用的系统资源
private connection newconnection()//新建一个数据库连接
public synchronized void timerevent() //定时器事件处理函数
}
public class dbconnectionmanager {
static private dbconnectionmanager instance;//连接池管理类的唯一实例
static private int clients;//客户数量
private arraylist drivers = new arraylist();//容器,存放数据库驱动程序
private hashmap pools = new hashmap ();//以name/value的形式存取连接池//对象的名字及连接池对象
static synchronized public dbconnectionmanager getinstance()//如果唯一的//实例instance已经创建,直接返回这个实例;否则,调用私有构造函数,创//建连接池管理类的唯一实例
private dbconnectionmanager()//私有构造函数,在其中调用初始化函数init()
public void freeconnection(string name, connection con)// 释放一个连接,//name是一个连接池对象的名字
public connection getconnection(string name)//从名字为name的连接池对象//中得到一个连接
public connection getconnection(string name, long time)//从名字为name
//的连接池对象中取得一个连接,time是等待时间
public synchronized void release()//释放所有资源
private void createpools(properties props)//根据属性文件提供的信息,创建//一个或多个连接池
private void init()//初始化连接池管理类的唯一实例,由私有构造函数调用
private void loaddrivers(properties props)//装载数据库驱动程序
}
public void init() throws servletexception
{
connmgr = dbconnectionmanager.getinstance();
}
public void destroy() {
connmgr.release(); super.destroy();
}
新闻热点
疑难解答