关于Tomcat连接池会话回收的问题. finalize只有在GC启动时才会调用,如果GC都没启动,那它就根本不会被调用了并不一定是程序结束GC就会启动。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 对,Java的垃圾回收不是变量用完马上就会调用的,实际的使用还是最好显式调用close()。 你在JavaBean中根本不应该保持Connection对象,应该在每次使用SQL语句之前从DataSource中获得并在使用完以后马上调用Close方法这样才是使用连接池的方法,实际上Close并不是真正的Close了连接,仅仅是放回了连接池的 不可能吧?我在tomcat的Log文件里确实看到,finalize被调用了.因为我的:System.out.println("关闭连接池!");在控制台显示了很多:关闭连接池!另外:我想不断的关闭连接:肯定要影响速度,我想在我的Session操作中,保持数据库的连接,这样可以省去打开数据库的大量时间.显示调用Close在什么地方呢?每个页面执行一次么?这样肯定是不对的.这样得的操作会是老牛拉破车,慢得受不了.不过还是感谢回复谢谢! 我以前就是采用这种方式,但是,连接最好时间的就是:try { ctx = new InitialContext(); if (ctx == null) { throw new Exception("没有匹配的环境"); } DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy"); if (ds == null) { throw new Exception("没有匹配数据库"); } conn = ds.getConnection(); stmt = conn.createStatement(); //ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); } catch (Exception e) { System.out.print(e.getMessage()); }如果每个连接都要获得一次,页面会慢得受不了。每个都获得肯定是不合理的。为什么不能保持连接到你不想用的时候再去掉呢? 不错,finalize()不是在每个javabean废弃之后就调用的,会话结束后你的连接javabean只是符合了回收的条件,并不一定会立即被回收。建议在每个页面中显式关闭连接,不会影响速度,用连接池的好处就在这里,因为实际上它与数据库的连接并没有变化,只有建立和数据库的连接才是费时的操作。 to kingfreng(东方岛主) : 谢谢您的回复!不过,我想问一下,你测试过么? 我有很多连续对数据库操作的JSP页面,在当前用户操作的过程中,需要持续的对数据库的连接。 我开始采用每个页面都关闭打开数据库连接池的方式,速度慢的无法忍耐! 因此我才采用这种把数据库连接做成Bean放到Session变量里面,保持对数据库的连接.这样的速度大大提高. 您说不会影响速度,是从什么角度说的呢? 数据库连接池就是解决楼主的问题的。如果你用Session保存连接,那么用连接池岂不是多此一举? 看来CSDN的专家不少!!可惜,真正做项目的感觉不是很多。大家都知道连接池的原理,认为Tomcat是万能的可以管理一切。 但是,我不知道大家是否跟踪过,对数据库操作真正耗时间的什么地方?在JBuilderX中,对下列语句进行单步跟踪: DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy"); if (ds == null) { throw new Exception("没有匹配数据库"); } conn = ds.getConnection(); 发现conn = ds.getConnection();出现非常明显的停顿,大概2秒钟!!! 如果大家都认为可以在每个页面另外从连接池中获取连接,那么我没有什么话说,也许大家的机器都是我机器速度的N倍!!! 另外:所有的操作,即使是速度很快连接池操作,采用页面间page/session/Application等的对象保留都是可以选择的,具体才有何种Scope都要经过分析。我采用跟踪发现,finalize其实是执行的,对连接的Close已经执行了。不过,如果我在调试过程中,点击调试的中断,Finalize就不会执行,因此会保留这些垃圾连接。同时我的整个网站中,对数据库的连接大概有几十次,每个页面都要有同时多次连接,而一个用户的页面操作都要剩余两个会话,采用Oracle的立即中断会话都关闭不了! 我期待专家能帮帮我!谢谢。 我还是觉得楼主的思路有问题!1、ds.getConnection()方法确实耗时间,所以才用连接池保存一定数量的连接,这些连接在使用时几乎不用重新建立连接了,因为第一次使用时会执行getConnection()方法,使用后只是放回连接池并没有关闭连接,所以不用每次都重新getConnection()。2、如果使用Session来保存连接对象的话,首先无法预知何时才能被垃圾回收器发现并回收,白白浪费资源;其次需要将连接对象在服务器和客户端传来传去;再次不利于层次清楚的设计。3、长期占用并不使用连接,使数据库连接数量增加,因为其它用户使用时必须重新建立连接,从长效上看,用Session方法来保存连接其实执行getConnection()方法的次数要远远多于使用连接池的方法。不知说的是否正确,希望大家讨论! to hq1305018(跃强): 非常感谢您的回复! 我想请教一下,我的连接池应该怎么写?可能Session会存在很多问题。你们都说不能用Session。好,我改了。 今天我用了一上午时间,我把所有的连接Bean都改成了Page,并且在每个页面数据库连接的最后,都加入了Close。 结果是:每一个对数据库的操作都要等到好几秒钟,有的甚至几十秒。 所谓的连接池的优越性根本就没有体现出来,我想知道,ds.getConnection()这一句只要你调用它,就会很耗费时间,请问大家是如何处理的? 我的连接池代码配置都在上面,请专家们看看为什么我的速度这么慢?而当我改回到Session方式后,速度飞快? 我想这个问题大家要换个角度考虑,首先,session是针对具体客户的,把数据库连接保存在session中对单个特定的客户来说速度当然很快,因为对他而言只需要建立一次连接,但是这样长期保持连接,对服务器来说压力很大,很简单,当客户量很大的时候由于连接池中的连接被每个客户占用没有释放,所以服务器要建立很多连接,速度会很慢,达到一定程度,所有客户的数据库连接都会很慢。我想很多人只是单重从学习和技术的角度考虑这个问题,而真正做项目的可能不多,但是所有的技术最终都要转化为生产力,要不然就没有什么意义了。连接池就是有这种商业性和他的实用性,否则就不会诞生。总的来说,连接池很有他的使用价值,这是一个商业价值很高的技术,在真正的项目运用中使用session保持数据库连接是不现实的,只能在特定的情况下适当的使用。请多多指教! Tomcat:5.0.19 有连接池的bug;请用5.0.25版 非常感谢stone_q(qq)的回复。但是,我现在的问题是,如果不采用Session ,我的速度是不能被客户允许的。我在寻找折中的办法。to fanciex(法西施<--) : 我改成了5.0.26还是不行。你敢肯定5.0.25没问题么?如果确定可以,我就重新安装。 jsp循环数组 我用tomcat部署的应用用localhost:8080可以访问 web开发中的权限问题讨论!!! 有没有实现带checkbox的XLoadTree例子??? 用servlet开发的过滤器不能编译! 如何保持一个其它服务器上网站的session 写了个自定义标签,有问题! 用 javabean 连接数据库,总是失败,看不懂出了什么问题,郁闷中…… 超级简单问题,大送分! 简单问题 高手指点 急 怎样在servlet中得到PageContext对象 PageContext pageContext=????? 再现等 招java程序员
我在tomcat的Log文件里确实看到,finalize被调用了.因为我的:System.out.println("关闭连接池!");
在控制台显示了很多:关闭连接池!另外:
我想不断的关闭连接:肯定要影响速度,我想在我的Session操作中,保持数据库的连接,这样可以省去打开数据库的大量时间.显示调用Close在什么地方呢?每个页面执行一次么?这样肯定是不对的.这样得的操作会是老牛拉破车,慢得受不了.不过还是感谢回复
谢谢!
try {
ctx = new InitialContext();
if (ctx == null) {
throw new Exception("没有匹配的环境");
}
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy");
if (ds == null) {
throw new Exception("没有匹配数据库");
} conn = ds.getConnection();
stmt = conn.createStatement(); //ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
}
catch (Exception e) {
System.out.print(e.getMessage());
}
如果每个连接都要获得一次,页面会慢得受不了。每个都获得肯定是不合理的。为什么不能保持连接到你不想用的时候再去掉呢?
建议在每个页面中显式关闭连接,不会影响速度,用连接池的好处就在这里,因为实际上它与数据库的连接并没有变化,只有建立和数据库的连接才是费时的操作。
我有很多连续对数据库操作的JSP页面,在当前用户操作的过程中,需要持续的对数据库的连接。 我开始采用每个页面都关闭打开数据库连接池的方式,速度慢的无法忍耐!
因此我才采用这种把数据库连接做成Bean放到Session变量里面,保持对数据库的连接.这样的速度大大提高. 您说不会影响速度,是从什么角度说的呢?
但是,我不知道大家是否跟踪过,对数据库操作真正耗时间的什么地方?
在JBuilderX中,对下列语句进行单步跟踪:
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy");
if (ds == null) {
throw new Exception("没有匹配数据库");
} conn = ds.getConnection();
发现conn = ds.getConnection();出现非常明显的停顿,大概2秒钟!!! 如果大家都认为可以在每个页面另外从连接池中获取连接,那么我没有什么话说,也许大家的机器都是我机器速度的N倍!!! 另外:所有的操作,即使是速度很快连接池操作,采用页面间page/session/Application等的对象保留都是可以选择的,具体才有何种Scope都要经过分析。我采用跟踪发现,finalize其实是执行的,对连接的Close已经执行了。不过,如果我在调试过程中,点击调试的中断,Finalize就不会执行,因此会保留这些垃圾连接。同时我的整个网站中,对数据库的连接大概有几十次,每个页面都要有同时多次连接,而一个用户的页面操作都要剩余两个会话,采用Oracle的立即中断会话都关闭不了! 我期待专家能帮帮我!谢谢。
1、ds.getConnection()方法确实耗时间,所以才用连接池保存一定数量的连接,这些连接在使用时几乎不用重新建立连接了,因为第一次使用时会执行getConnection()方法,使用后只是放回连接池并没有关闭连接,所以不用每次都重新getConnection()。
2、如果使用Session来保存连接对象的话,首先无法预知何时才能被垃圾回收器发现并回收,白白浪费资源;其次需要将连接对象在服务器和客户端传来传去;再次不利于层次清楚的设计。
3、长期占用并不使用连接,使数据库连接数量增加,因为其它用户使用时必须重新建立连接,从长效上看,用Session方法来保存连接其实执行getConnection()方法的次数要远远多于使用连接池的方法。不知说的是否正确,希望大家讨论!
非常感谢您的回复!
我想请教一下,我的连接池应该怎么写?可能Session会存在很多问题。你们都说不能用Session。好,我改了。 今天我用了一上午时间,我把所有的连接Bean都改成了Page,并且在每个页面数据库连接的最后,都加入了Close。 结果是:每一个对数据库的操作都要等到好几秒钟,有的甚至几十秒。 所谓的连接池的优越性根本就没有体现出来,我想知道,ds.getConnection()这一句只要你调用它,就会很耗费时间,请问大家是如何处理的? 我的连接池代码配置都在上面,请专家们看看为什么我的速度这么慢?而当我改回到Session方式后,速度飞快?
请多多指教!
但是,我现在的问题是,如果不采用Session ,我的速度是不能被客户允许的。我在寻找折中的办法。to fanciex(法西施<--) :
我改成了5.0.26还是不行。你敢肯定5.0.25没问题么?如果确定可以,我就重新安装。