论坛首页 Java版 Tomcat

Tomcat连接池原理讨论

浏览 10481 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2004-05-25
最近偶尔有个同事在tomcat連接池上提了一个疑问,引发我们部门地一番争论,但还是有分歧,不过通过一番查翻资料,疑点越来越集中,现在说说我的问题:
我们地统一点:
1.用户释放连接后,连接被回收到连接池,这个连接仍然是可用的。
如果一个连接等待了一段时间(连接池的最大空闲时间,可设置)仍然没有
人来请求连接,那么它将被彻底释放。当然,如果连接池中的连接个数已经
等于连接池的最小连接数(可设置),那么它不会被释放。

2.以tomcat连接池为例,tomcat启动后,假设我设置的最小连接数为5,那么这时候(此Tomcat下的程序没有启动)Tomcat是否和后台地数据库建立5条连线(session)呢?答案:不是.

3.我们的分歧点:注意第一点说的"用户释放连接后",什么叫用户释放连接,我把操作地页面关掉,还是在程序里调用conn.close,如果我在程序里面手动地close,那么我关闭的是连接池里的连接吗,还是把连接还给连接池,也就是说,我手动close连接是否有必要呢?
希望听听大家地意见.
btw:这个问题不知道该发到哪个版面,看到此版是java编程,所以就......^^
   
时间:2004-05-25
conn.close()将数据库连接扔回给连接池,并没有真正的关闭。
   
0 请登录后投票
时间:2004-05-25
對於第三點,用戶釋放連接可以是頁面關掉也可以是自己close,不過建議自己手動close
   
0 请登录后投票
时间:2004-05-25
必须显式调用close()方法,包括Connection,ResultSet,Statement,PreparedStatement的。
   
0 请登录后投票
时间:2004-05-25
swallor 写道
必须显式调用close()方法,包括Connection,ResultSet,Statement,PreparedStatement的。

对,tomcat文档中有这一说。对于那些没有主动close的con,dbcp也会除理,通过配置:
[code:1]
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>

[/code:1]
   
0 请登录后投票
时间:2004-05-27
不怎么仔细研究.不过连接池都有超时的设置,只要不是主动关闭的,到了超时状态就会回收.
不过还是主动好.因为可以控制是什么时候释放了..
   
0 请登录后投票
时间:2004-05-28
首先自己要想清楚,为什么要使用连接池,就不需要问这样的问题了。

连接池最基本的目的:
1、重用连接,节省连接资源;
2、免去建立连接操作,提高效率

所以:
1、connection.close当然不会关闭实际连接,只是归还连接池!
2、如果等待系统自动回收connection,也就是说即使你不使用连接也不让别人用,那还要连接池来干嘛?!
   
0 请登录后投票
时间:2004-05-31
同意楼上的观点
连接池要是能用conn.close()随便关掉,还要连接池干什么。关掉的是用户和连接池的连接而已。
   
0 请登录后投票
时间:2004-06-01
flyisland 写道
首先自己要想清楚,为什么要使用连接池,就不需要问这样的问题了。

连接池最基本的目的:
1、重用连接,节省连接资源;
2、免去建立连接操作,提高效率

所以:
1、connection.close当然不会关闭实际连接,只是归还连接池!
2、如果等待系统自动回收connection,也就是说即使你不使用连接也不让别人用,那还要连接池来干嘛?!


同意flyisland的观点,再有一点点补充。

个人觉得不同的连接池实现都有自己的考虑,但会遵循一些基本规则:
比如楼主列出的
第一点:既要保持一定数量的连接供使用,同时要防止存在很多空闲的连接,浪费资源。
第二点:至于系统启动时,是否需要同步创建最小连接数的连接呢,还是等到有需要时再创建连接?这就取决于实现者的选择了。我个人认为后者比较合适,当然如果有特殊要求的除外。

另外,还有如:connection.close不会关闭实际连接,只是归还连接池!等等...
   
0 请登录后投票
时间:2004-06-03
[code:1]package com.dalong.connectionpool;
import java.util.HashMap;
import java.util.Vector;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.*;
/**
* <p>Title: </p>
* <p>Description: test</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: home</p>
* @author dalong
* @version 1.0
*/

public class ConnectionPool {

//连接池的管理器,首先初始化,仅仅有一个对象,管理连接池
private static HashMap connectionPoolManager=new HashMap();
//没有用过的连接池,用vector实现同步
private static Vector noUseConnectionPool;
//没有用过的连接池
private static HashMap nowUseConnectionPool;

private static String dbDriver="odbc:jdbc:OdbcJdbcDriver";
private static String dbUrl="dalong@XX";
private static String userName="dalong";
private static String userPassword="dalong";

//默认为100个连接池
private static int MAX_POOL=100;

//singleTon 设计模式
private ConnectionPool(String driver,String url,String name,String password,int max)
throws ClassNotFoundException {
Class.forName(driver);
dbUrl=url;
userName=name;
userPassword=password;
MAX_POOL=max;
}
public static ConnectionPool getConnManagerInstance(String poolName)
throws ClassNotFoundException{
ConnectionPool tempPool=(ConnectionPool)connectionPoolManager.get(poolName);
if(tempPool==null){
tempPool=new ConnectionPool(dbDriver,dbUrl,userName,userPassword,MAX_POOL);
connectionPoolManager.put(poolName,tempPool);
return tempPool;
}else
return tempPool;
}

//通过连接池获得真正的链接
public static Connection getConnection() throws java.sql.SQLException{
Connection conn=null;
synchronized(noUseConnectionPool){
if(noUseConnectionPool.size()>0){
conn=(Connection)noUseConnectionPool.firstElement();
noUseConnectionPool.remove(conn);
return conn;
}
}
//如果数据库连接池没有链接了,自己创建一个
if(conn==null){
conn=createConnection(dbDriver,dbUrl,userName,userPassword);
}else if(conn.isClosed()){
nowUseConnectionPool.remove(conn);
conn=createConnection(dbDriver,dbUrl,userName,userPassword);
}
conn.setAutoCommit(false);
nowUseConnectionPool.put(conn,conn);
return conn;
}

//如果连接池没有链接了,就需要产生一个链接
private static Connection createConnection(String driver,String url,String user,String password)
throws java.sql.SQLException{
Connection conn=DriverManager.getConnection(url,user,password);
return conn;
}
public static void releaseConnection(Connection conn,boolean isCommit)
throws java.sql.SQLException{
if(isCommit)
conn.commit();
else
conn.rollback();
nowUseConnectionPool.remove(conn);
if(noUseConnectionPool.size() + nowUseConnectionPool.size()<MAX_POOL){
synchronized(noUseConnectionPool){
noUseConnectionPool.add(conn);
}
}else{
conn.close();
}
}

public static void main(String[] args) {
//测试模拟10个客户
for (int i = 0; i < 10; i++) {
try {
//xxxx 一般为属性文件读取
ConnectionPool pool = ConnectionPool.getConnManagerInstance("xxxx");
Connection conn = pool.getConnection();

}catch (SQLException ex1) {
//处理异常
}
catch (ClassNotFoundException ex) {
//处理异常
}
}
}
}
[/code:1]
   
0 请登录后投票
论坛首页 Java版 Tomcat

跳转论坛:
JavaEye推荐