Tomcat5的SQL Server数据库连接池问题
 
[ 双击自动滚屏 ] [ 打印本页 ]  [ 发布日期: 2006-04-26]  [ 被阅次数    699  次]    [字体: ]  
服务器连接池:
<Context path="/SQL" docBase="D:\SQL_JSP" debug="0" reloadable="true" crossContext="true">
    <Resource name="jdbc/bn" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/bn">
    <parameter>
        <name>factory</name>
        <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
        </parameter>

    <parameter>
        <name>driverClassName</name>
        <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
        </parameter>

    <parameter>
        <name>url</name>
        <value>jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=jspdev</value>
        </parameter>

    <parameter>
        <name>username</name>
        <value>cyg</value>
        </parameter>

    <parameter>
        <name>password</name>
        <value>84175971</value>
        </parameter>

    <parameter>
        <name>maxActive</name>
        <value>20</value>
        </parameter>

    <parameter>
        <name>maxIdle</name>
        <value>10</value>
        </parameter>

    <parameter>
        <name>maxWait</name>
        <value>-1</value>
        </parameter>
</ResourceParams>
</Context>

Java工具类
package biz;

import java.sql.*;
import javax.sql.*;
import java.util.Vector;
import java.util.Date;
import javax.naming.*;

public class connpool{ // 连接池类
    private int maxconn; //最大连接数
    private int nActive; //已创建的连接数
    private Vector freeCons=new Vector(); //存储当前可用连接的数组

    private Context initCtx = null;   //Context 上下文类型
    private Context ctx =null;
    private DataSource ds=null;

    public connpool()
    {
        this.maxconn=20;
        this.nActive =0;
        try{
            initCtx = new InitialContext(); //初始化上下文,可以读配置文件如:web.xml
            if(initCtx==null) throw new Exception("Initial Failed!");
            ctx = (Context) initCtx.lookup("java:comp/env");
             //szJdbc="jdbc/jspdev" 此值在Tomcat的SERVER.XML文件中配置
            if(ctx!=null)  ds= (DataSource) ctx.lookup("jdbc/bn");
            if(ds==null)   throw new Exception("Look up DataSource Failed!");     //以上这是从配置文件读取上下文的一种方法!
//参数在上下文中定义
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
    }

    public void SetMaxConn(int n){//默认最大连接数为 20 ~ 200;
        if(n<20)  n=20;
        if(n>200) n=200;
        this.maxconn =n;
    }

    public synchronized void freeConnection(Connection con) //归还连接
    {  //synchronized关键字定义可异步同时连接
        try{
            if(con.isClosed()){
                con=null;    //System.out.println("Connection is Closed\n");
            }
            else{
                freeCons.addElement(con);  
                System.out.println("Add Exists Connection,Current Conut=" + freeCons.size());
            }
        }
        catch(Exception e){System.out.println(e.getMessage());}
        //notifyAll();
    }

    public synchronized Connection getConnection(long timeout) //取得一个连接(指定超时时间)
    {
        long startTime=new Date().getTime(); //记录超时用
        Connection con=null;
        while(con==null){
            if(freeCons.size()>0){//在有可用的连接,选用可用连接
                con=(Connection) freeCons.firstElement(); //从数组中取得第一個    把能用的连接取走了一个,当然再能用的连接中,减去一个了
                freeCons.removeElementAt(0); //並从数组中刪除
                try{
                  if(con.isClosed()){ //如果已关闭,则将已创建连接减一
                        nActive--;
                        con=null;
                    }
                }
                catch(Exception e){System.out.println(e.getMessage());}
                if(con!=null) System.out.println("Get Exists Connection\n");
            }else if(nActive<maxconn){ //没有可用连接且已创建的连接数小于最大数時,创建新连接
                con=newConnection();
                if(con!=null) System.out.print("Create New Connection ******" + nActive );
            }
            if(con!=null) break; //取得可用连接后,则直接退出等待
            //否则,进行等待0.5s,进行下一次获取连接的操作
            try{
                wait(500); //等待0.5秒
            }
            catch(InterruptedException e) {}
            if((new Date().getTime()-startTime)>=timeout){
                System.out.println("Connection timeout\n");
                break; //超时则退出
            }
        }
        return con;
    }

    public void release(){ //关闭所有连接
        int i=freeCons.size();
        int j=0;
        for (j=0;j<i;j++){
            Connection con=(Connection)freeCons.elementAt(j);
            try{
                con.close();
            }
            catch(SQLException e) {
                System.out.println("无法关闭连接池中的当前连接");
            }
        }
        freeCons.removeAllElements();
        nActive=0;
    }

    private Connection newConnection(){ //创建一个新连接
        Connection con=null;
        try{
            con=ds.getConnection();
            if(con==null) throw new Exception("Create Connection Failed!");
            else nActive++;
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        return con;
    }
}

JSP页面调用该Java
<%@ page language="java" import="java.sql.*"%>
<html>
<head><title>你好!我是小肥猫</title></head>
<jsp:useBean id="vCon" scope="application" class="biz.connpool"/>
<body>
<%!
    Connection con=null;
    java.sql.Statement stmt=null;
%>

<%
try{
    if(con==null) con=vCon.getConnection(10000); //最大等待时间为10s
    stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
}   //两个结果集 第一个参数时说结果集是不可滚动的,只能向前滚!第二个是结果集是只读的
catch(Exception e){
    System.err.println(e.getMessage());
}

ResultSet rs=stmt.executeQuery("select * from 书籍");

  while(rs.next())
    {
      out.println(rs.getString("商品编号"));
    }
stmt.close();
vCon.freeConnection(con);
con=null;
%>
</body>
</html>