Topic: 关于Tomcat的Connection管理问题 |
Print this page |
1.关于Tomcat的Connection管理问题 | Copy to clipboard |
Posted by: cxp108 Posted on: 2006-09-11 10:52 Tomcat 5.5 Red Hat Linux 9.0 PostgreSQL 8.1 使用以下方式获得连接
代码一开始运行正常,但经过多次运行后,出现以下情况 1. ds.getConnection()被完全阻塞了,不返回 2. 不会出现任何异常 3. 以上现象持续,直至重启Tomcat为止 采取以下手段都无法解决问题: 1. 手动关闭掉所有ResultSet , Statement , Connection 2. 不关闭所有ResultSet, Statement,Connection 3. 关闭ResultSet,Statement, 但不关闭Connection 4. 清空所有指向Connection 的引用 我分析一下以后觉得应该是Tomcat内部的ConnectionPool机制引起的,但详细原理并不清楚。 请问,该问题如何解决? |
2.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-12 09:02 Tomcat 5.5 Windows XP SQL Server 2000 ds是DateSource的一个对象么? 原因我看不出来,不过,我可以将我们常用的连接池配置列出来,也许LZ能够找到一些灵感: WEB-INF/tld/web.xml |
3.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-12 09:09 停电了! ..... |
4.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-12 09:15 <!-- Database proxool --> <servlet> <servlet-name>ServletConfigurator</servlet-name> <servlet-class> org.logicalcobwebs.proxool.configuration.ServletConfigurator </servlet-class> <init-param> <param-name>xmlFile</param-name> <param-value> WEB-INF/config/sqlserver_proxool.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 写了一个配置文件,WEB-INF/config/sqlserver_proxool.xml <?xml version="1.0" encoding="UTF-8"?> <!-- the proxool configuration can be embedded within your own application's. Anything outside the "proxool" tag is ignored. --> <something-else-entirely> <proxool> <alias>att</alias> <driver-url> jdbc:microsoft:sqlserver://localhost:1433;Databasename=att </driver-url> <driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class> <driver-properties> <property name="user" value="sa" /> <property name="password" value="sa" /> </driver-properties> <maximum-connection-count>100</maximum-connection-count> <house-keeping-test-sql> select CURRENT_DATE </house-keeping-test-sql> </proxool> </something-else-entirely> 注:连接池驱动(proxool-0.8.3.jar),如果需要,把你邮箱贴出来吧! 后面写的就是一个工具类了! |
5.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-12 09:18 /******************************************************************************** 模块名 : 数据库管理器 文件名 : DatabaseManager.java 相关文件 : 文件实现功能 : 与数据库建立连接、断开连接、执行查询和更新操作 作者 : William@Passion Software 版本 : 1.1 -------------------------------------------------------------------------------- 备注 : <灵活性不够> -------------------------------------------------------------------------------- 修改记录 : 日 期 版本 修改人 修改内容 31/07/2006 1.1 <William> <proxool连接池> *******************************************************************************/ package com.passionsoft.util; import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class DatabaseManager { private static final Log logger = LogFactory.getLog(DatabaseManager.class); // 批处理 private String[] str; // 批处理语句包 private static int flag = 0; // 数组指针 private int no = 0; // 语句数目 public DatabaseManager() { } /** * 从连接池获得一个数据库连接 * * @return Connection * */ public Connection getConnection() { Connection conn = null; try { Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); conn = DriverManager.getConnection("proxool.att"); } catch (ClassNotFoundException e) { // 在classpath中未找到合适的驱动 logger.error(e.getMessage()); } catch (SQLException e) { // 获取连接失败 logger.error(e.getMessage()); } if (conn != null) { if (logger.isDebugEnabled()) { logger.debug("Get a Connection from Connection Pool"); } // System.out.println("Get a Connection from Connection Pool"); } return conn;// 返回该Connection } /** * 传入执行查询的语句,返回结果集 * * @param Connection * conn * @param String * sql * @return ResultSet */ public ResultSet executeQuery(Connection conn, String sql) { Statement stmt = null;// 声明Statement stmt ResultSet rs = null;// 声明ResultSet rs if (conn != null) { // Connection 不为null,执行查询 // 若debug模式开启,则输出debug 信息 if (logger.isDebugEnabled()) { logger.debug(sql); } try { stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);// 通过Connection创建一个Statemet rs = stmt.executeQuery(sql);// 执行查询语句, } catch (SQLException sqlex) { logger.error(sqlex.getMessage()); return null; } return rs; } else { // Connection 为null,输出debug信息,返回null if (logger.isDebugEnabled()) { logger.debug("Connection is null"); } return null; } } /** * 传入执行数据更新的语句,返回更新结果,成功执行为真 * * @param Connection * conn * @param String * sql * @return boolean */ public boolean executeUpdate(Connection conn, String sql) { boolean status = false;// 执行结果,默认为false Statement stmt = null;// 声明Statement stmt if (conn != null) { // Connection 不为null,执行更新 // 若debug模式开启,则输出debug 信息 if (logger.isDebugEnabled()) { logger.debug(sql); } try { stmt = conn.createStatement();// 通过Connection创建一个Statemet int count = stmt.executeUpdate(sql);// 执行更新数据操作,返回影响的行数 // 根据count值,判断执行的成功或失败 if (count > 0) status = true; } catch (SQLException sqlex) { logger.error(sqlex.getMessage()); } } else { // Connection 为null,输出debug信息,返回false if (logger.isDebugEnabled()) { logger.debug("Connection is null"); } } return status; } /** * 数据库语句批处理操作 * @param str[] * 批处理语句包 * @param conn */ public boolean executeUpdateBatch(Connection conn, String[] str) { boolean status = false; //执行结果 Statement stmt = null; if(conn != null){ try{ // 当全部批处理都正确时,才执行数据提交执行;否则所有语句都不被执行 conn.setAutoCommit(false); stmt = conn.createStatement(); int[] rows; //添加批处理操作 for(int i=0;i<str.length;i++) stmt.addBatch(" " + i +" " + str[i]); rows = stmt.executeBatch(); //提交事务 conn.commit(); if(rows.length == str.length) status = true; }catch(BatchUpdateException bue){ int[] success_rows; success_rows = bue.getUpdateCounts(); System.err.println("Success Counts: " + success_rows); }catch(SQLException e){ e.printStackTrace(); } } return status; } /** * 批处理操作的辅助方法——将sql语句添加进处理批次中 * * @param sql * 处理语句 * @return */ public void addSql(String sql) { str[flag] = sql; flag++; // 防止数组越界 if (flag >= no) flag = 0; } /** * 批处理操作的辅助方法——设置批处理语句数目 * * @param i * 处理语句数目 */ public void setBatch(int i) { str = new String[i]; no = i; } /** * 批处理操作的辅助方法——获取处理语句包 * * @return */ public String[] getBatch() { flag = 0; // 获取处理语句包后,将指针拨回 return str; } /** * 释放从连接池取得的连接 * * @param Connection * conn */ public void releaseConnection(Connection conn) { // 释放连接 if (conn != null) { try { conn.close(); if (logger.isDebugEnabled()) { logger.debug("Released a Connection to Connection Pool"); } // System.out.println("Released a Connection to Connection // Pool"); } catch (SQLException sqlex) { logger.error(sqlex.getMessage()); } finally { conn = null; } } } } 注:william是我们团队的老大,这里面只有相关批处理操作是我写的,还没有经过测试哦。 Log对象是用的appach的一个调试工具类 |
6.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-12 09:24 覆写了executeUpdate、executeQuery方法,很多琐碎的东西都隐藏了,算一个小小的变通吧! 至少,数据库操作的方法,变得很精简,寥寥几行...... 我们都是还没出去的大学生,自然没有保护意识,反正都是从网上搂别人的! |
7.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: cxp108 Posted on: 2006-09-12 09:30 谢谢了 其实我用的方式就是网络上流传最简单的那种 1. 在server.xml中注册一个数据库连接 2. 在web.xml这中声明这个连接 3. 然后在servlet中使用这个连接 仅仅是让Tomcat去管理连接而已,我想问的是如果让Tomcat管理数据库连接,那么我们在使用完数据库连接后要手动进行什么处理么? 你们自己实现的连接池么? |
8.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: lisliefor Posted on: 2006-09-13 13:09 每个对数据库操作的方法,finally里,都调用 releaseConnection()方法,释放连接! 连接池参照别人的,不过改了一部分! 虽然,看上去比较繁琐,但是,这些繁琐的事情都留给了程序员! 很多实现都隐藏了,所以在使用的时候,相对比较方便! |
9.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: wsfx Posted on: 2006-09-14 16:35 我估计LZ是用了connection之后没有手工释放,导致连接一直被占用,当数据库连接到达一定数量之后,出现阻塞.记得用完之后应马上connnection.close() |
10.Re:关于Tomcat的Connection管理问题 [Re: cxp108] | Copy to clipboard |
Posted by: cxp108 Posted on: 2006-09-15 08:39 我曾经尝试关闭所有的connection、Statement和ResultSet,并将它们的Reference指成null,但是都起不到任何作用。 |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |