|
锁定老贴子 主题:Tomcat连接池原理讨论
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2004-05-25
最近偶尔有个同事在tomcat連接池上提了一个疑问,引发我们部门地一番争论,但还是有分歧,不过通过一番查翻资料,疑点越来越集中,现在说说我的问题:
我们地统一点: 1.用户释放连接后,连接被回收到连接池,这个连接仍然是可用的。 如果一个连接等待了一段时间(连接池的最大空闲时间,可设置)仍然没有 人来请求连接,那么它将被彻底释放。当然,如果连接池中的连接个数已经 等于连接池的最小连接数(可设置),那么它不会被释放。 2.以tomcat连接池为例,tomcat启动后,假设我设置的最小连接数为5,那么这时候(此Tomcat下的程序没有启动)Tomcat是否和后台地数据库建立5条连线(session)呢?答案:不是. 3.我们的分歧点:注意第一点说的"用户释放连接后",什么叫用户释放连接,我把操作地页面关掉,还是在程序里调用conn.close,如果我在程序里面手动地close,那么我关闭的是连接池里的连接吗,还是把连接还给连接池,也就是说,我手动close连接是否有必要呢? 希望听听大家地意见. btw:这个问题不知道该发到哪个版面,看到此版是java编程,所以就......^^ 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2004-05-25
conn.close()将数据库连接扔回给连接池,并没有真正的关闭。
|
|
| 返回顶楼 | |
|
时间:2004-05-25
對於第三點,用戶釋放連接可以是頁面關掉也可以是自己close,不過建議自己手動close
|
|
| 返回顶楼 | |
|
时间:2004-05-25
必须显式调用close()方法,包括Connection,ResultSet,Statement,PreparedStatement的。
|
|
| 返回顶楼 | |
|
时间: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] |
|
| 返回顶楼 | |
|
时间:2004-05-27
不怎么仔细研究.不过连接池都有超时的设置,只要不是主动关闭的,到了超时状态就会回收.
不过还是主动好.因为可以控制是什么时候释放了.. |
|
| 返回顶楼 | |
|
时间:2004-05-28
首先自己要想清楚,为什么要使用连接池,就不需要问这样的问题了。
连接池最基本的目的: 1、重用连接,节省连接资源; 2、免去建立连接操作,提高效率 所以: 1、connection.close当然不会关闭实际连接,只是归还连接池! 2、如果等待系统自动回收connection,也就是说即使你不使用连接也不让别人用,那还要连接池来干嘛?! |
|
| 返回顶楼 | |
|
时间:2004-05-31
同意楼上的观点
连接池要是能用conn.close()随便关掉,还要连接池干什么。关掉的是用户和连接池的连接而已。 |
|
| 返回顶楼 | |
|
时间:2004-06-01
flyisland 写道 首先自己要想清楚,为什么要使用连接池,就不需要问这样的问题了。
连接池最基本的目的: 1、重用连接,节省连接资源; 2、免去建立连接操作,提高效率 所以: 1、connection.close当然不会关闭实际连接,只是归还连接池! 2、如果等待系统自动回收connection,也就是说即使你不使用连接也不让别人用,那还要连接池来干嘛?! 同意flyisland的观点,再有一点点补充。 个人觉得不同的连接池实现都有自己的考虑,但会遵循一些基本规则: 比如楼主列出的 第一点:既要保持一定数量的连接供使用,同时要防止存在很多空闲的连接,浪费资源。 第二点:至于系统启动时,是否需要同步创建最小连接数的连接呢,还是等到有需要时再创建连接?这就取决于实现者的选择了。我个人认为后者比较合适,当然如果有特殊要求的除外。 另外,还有如:connection.close不会关闭实际连接,只是归还连接池!等等... |
|
| 返回顶楼 | |
|
时间: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] |
|
| 返回顶楼 | |













