| [摘要]:在远程教学中,往往是很多人同时在线进行网络教学活动,这样必然会涉及到大量的数据库访问,因此,面对大量并发性的数据库访问,必须要采取一种方式对数据库的连接访问进行优化,本文正是在对传统链接技术进行了详尽分析的基础上引入的这样一种有效的优化方案――数据库链接池技术,并详细介绍了此技术的特点、技术原理以及实施策略。
[关键词]:数据库,数据库连接,连接池,WEB
1. 问题的提出
从略。
2. 传统的数据库连接方式
在传统的数据库连接程序中,主要有以下几个步骤(假设数据源和数据库驱动都准备好了):
(1)在程序中创建一个JDBC驱动程序的实例。
(2)通过JDBC驱动程序的实例创建一个数据库连接。
(3)通过JDBC连接创建一个Statement对象并用此对象进行SQL操作。
(4)关闭数据库的连接。
我们可以看到下面的连接数据库的java代码。我们是把对数据库的操作封装在一个javabean中的,在导入了java.sql.*类包并声明必要的变量后就可以实现数据库的连接了。
从略。
使用这种数据库连接方式,系统会为每个请求建立一个新的数据库连接,这种处理方式看上去简单直接,但是,当服务器的访问量很大、并发请求的数量很多时,对于每个执行JSP实例的线程都创建自己的数据库连接,并直接与RDBMS引擎通信,就会使数据库的运行效率急剧下降,大大增加系统开销,更加严重的情况甚至可以导致服务器瘫痪。对于一次或几次操作来讲,或许你觉察不到系统的开销,但是,对于WEB程序来讲,即使在某一较短的时间段内,其操作请求数都会是数十次甚至上百次,在这种情况下,系统开销是相当大的。在JDBC中,一个连接对象表示一个本机数据库连接,而创建数据库连接对象则是非常耗费资源的,这样就会造成内部资源的严重消耗。事实上,在一个基于数据库的WEB系统中,建立数据库连接的操作将是系统中代价最大的操作之一。
还有,使用这种数据库连接方式,你必须去管理每一个连接,确保他们能被正确关闭,如果出现程序异常而导致某些连接未能关闭,将导致数据库系统中的内存泄露,最终我们将不得不重启数据库。
针对以上问题,可以想到采用一个全局的Connection对象,创建后就不关闭,以后程序一直使用它,这样就不存在每次创建、关闭连接的问题了。但是,同一个连接使用次数过多,将会导致连接的不稳定,进而会导致WEB
SERVER的频频重启。故而,这种方法也不可取。所以,我们使用数据库连接池技术来解决这个问题。
3. 使用数据库连接池(Connection Pool)技术
3.1 连接池的基本原理
连接池最简单的思想就是预先建立一些连接,放置在内存对象中以备使用。当程序中需要建立数据库连接时,只需从内存中取一个来用而不用重新建一个连接。同样,使用完毕后,只需将此连接放回到内存中即可,而连接的建立和断开都有连接池自身来管理。
池是一个很普遍的概念,和缓冲存储机制有相近的地方,都是缩减了访问的环节,但它更注重于资源的共享。池中有许多已经建立的连接,本来需要与数据库的连接的地方,就都改为和池相连了。

图1基本原理
3.2 工作机制
连接池主要由DBConnectionManager类和ConnectionPool类组成。连接池管理程序DBConnectionManager类将创建并维护数据库连接池,它负责管理用于实际创建数据库连接的ConnectionPool类。在一个特定的连接池中,所有连接都将连接到同一个JDBC
URI,即同一个主机、数据库实例及登陆ID。在连接池中单个线程发出数据库连接请求,通过连接池管理程序得到这个连接,而其他线程就不会得到这个数据库连接了,此线程使用结束后,该线程将连接交还给连接池管理程序,以分配给其他等待连接的请求线程。这里连接池充分利用JAVA的线程同步机理,使当前服务线程处于等待状态,直至有空闲的连接出现。JAVA服务线程对数据库访问完毕后,应向连接池释放连接,而不是关闭连接。

图2 工作机制
连接池可以设置成非常高效的方式,在连接池管理程序中,可在脚本中设置连接的最大数目、每个连接的最大使用次数等参数,从而控制同一时刻可同时处理的并发请求数。所有的当前请求都将被连接池管理程序按顺序锁定。对请求线程的锁定是通过应用程序代码进行的,且请求数量可以很大,不必担心超出缓冲容量限制。一旦将连接交还给连接池,该连接将由连接池管理程序分配给其他锁定的请求。如图2,当有很多数据库请求并超出了连接池中连接的数目时,只有先发出数据库请求的线程获得连接来访问数据库,其他连接暂时处于等待的锁定状态(图中用蓝色表示等待的线程),当线程完成数据库操作并释放连接后,被释放的连接将按顺序由其他线程获得,这样就可以大大节省服务器的资源。
4. 连接池的具体实现
连接池类中最重要的就是DBConnectionManager类和ConnectionPool类。读者可以轻易的从网上找到各种数据库的连接池的类包和配置文件,下面对这两个类作简单的介绍,并用一个实际的例子重点介绍怎样使用连接池完成想要的数据库操作。
4.1 ConnectionPool类
从略。
4.2 DBConnectionManager类
从略。
4.3在JavaBean中的连接池实现
我们所应用的远程教学系统是基于c/s结构的教学支持平台,采用了JAVA的jsp/servlet/javabean的技术实现,使用的是Apache
+Tomcat4.1作为Web及应用服务器,数据库是Microsoft SQL Server2000,数据库名称是"platform",把编译好的连接池类放入WEB-INF/classes相应的位置,设置db.properties属性文件,定义好数据库用户名、密码、初始化连接数目及最大连接数目等属性参数。我们应该尽量不要在jsp页面中操作数据库,而是应该把数据库的操作封装在JavaBean中。在这个实例中,我们通过javabean使用连接池从而操作数据库,给出了根据教师的id查询教师信息的程序,从这个实例中,我们可以看到是如何利用数据库连接池类在实际程序中应用的。
import java.sql.*;public class TeachInfo{
public String querySQL;
private int teaID;
public String teaName;
public String teaSex;
public String teaAddress;
public String teaPhone;
public String teaBirth;
public TeachInfo(){
teaID=0;
teaName="";
teaSex="";
teaAddress="";
teaPhone="";
teaBirth="";}public void setTeaID(int teaID){ this.teaID=teaID;}public
int getTeaID(){ return this.teaID;}
public void queryTeaInfo(){ //创建管理类的实例
DBConnectionManager dcm=DBConnectionManager.getInstance();//获得名为"platform"数据库的一个连接
Connection con = dcm.getConnection("platform"); PreparedStatement
pstmt=null; ResultSet rs = null; querySQL="SELECT * FROM
teaInfo WHERE teaID="+teaID;//初始化SQL语句
try{
pstmt = con.prepareStatement(querySQL);
rs = pstmt.executeQuery();
rs.next(); teaID=rs.getInt(1); teaName=rs.getString(2); teaSex=rs.getString(3);
teaAddress=rs.getString(4); teaPhone=rs.getString(5); teaBirth=rs.getString(6);
rs.close();
pstmt.close();
}catch(SQLException sqle){
System.out.println("SQLException: " + sqle.getMessage());
}
finally{
dcm.freeConnection("platform",con); //释放所获得的连接
}
}}我们所做的工作就是创建DBConnectionManager的实例,并由它来获得数据库的一个连接,当获得这个连接后,就可以进行数据库操作了,进行完数据库操作后,我们必须调用freeConnection()方法来释放此连接将其放回连接池中。其实,编程者完全可以不用理会具体的连接池内部是如何操作的,因为在面向对象的程序设计中,管理类DBConnectionManager封装了全部实现的细节,它已经悄悄的为你实现了全部的工作。
5. 结束语
从略。
参考文献
从略。
|