`
John_wu
  • 浏览: 8829 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

我的处女贴:连接池释放连接异常!

阅读更多
终于熬到注册第三天了,故迫不及待发表我的第一个帖子,因为最近已经被这东西折腾的不行了!这段时间做一网站,没有用到持久层,用Weblogic9.1做Web服务器(知道很浪费:))配了两个连接池,分别是局域网的另外两台机器上的,一个是SQLServer,一个是Oracle,这两个数据库的特点是SQLServer的访问量很大,因为很多别的系统在用,有时会报出“NetWork error IOException,The address already in use:connect” ,Oracle机烂---PIII900的机器,临时空间不够,连接数多了就会报出“ORA 04031 无法分配***字节的共享内存("large pool",.......)”,连接池的参数大概是设置5个初始连接,每次增长5个,最大值设的比较大-4000,整个系统大概有150人左右使用,但是SQLServer的连接池经常会到2000多个连接,甚至到3000多个,不知道是什么原因,另外我的代码部分是用一个单例类管理连接,一个多例类供外界调用,多例类中的代码格式是:
public List methodA(String sql){
    Connection conn=null;
    Statement stmt = null;
    ResultSet result=null;
    ....do something
    finally{
closeResult(result);
closeStatm(stmt);
closeConn(conn);
    }
}
分享到:
评论
18 楼 抛出异常的爱 2006-11-30  
deafwolf 写道
抱歉,我没从你的代码中看出单态的所在
对于公用的连接类,单态的应该是类里的DS,而不是对这个类加锁

public class ConnManager{
  private static DataSource dataSource=null;
  private ConnManager(){};
  public static Connection getConnection(){
    if(dataSource==null){
      dataSource=...;
    }
    return dataSource.getConnection();
  }
}



这个是正确的单例...

单例特点
1static DataSource (静态变量)
2  private ConnManager(){};(私有构造器)
3  public static Connection getConnection(静态公开的得到连接的方法)
17 楼 John_wu 2006-11-30  
抛出异常的爱 写道
方法一用单例..
方法二用池
才能不溢出
PS:你用的单例是错的...
单例是错的??呵呵,那就请给兄弟一点明示了
16 楼 抛出异常的爱 2006-11-30  
方法一用单例..
方法二用池
才能不溢出
PS:你用的单例是错的...
15 楼 deafwolf 2006-11-30  


多线程你加锁啊,再包一层就能处理多线程么
14 楼 John_wu 2006-11-30  
deafwolf 写道
理由何在?
因为就算这个类已经是单例了,但是一个实例在多线程的情况下也有可能产生多个DataSource对象吧。
13 楼 deafwolf 2006-11-30  
理由何在?
12 楼 John_wu 2006-11-30  
多谢“unifly”和“抛出异常的爱”的回复,看到大家一致的解决方案,我的这个帖子被踢到新手区也是理所当然的啦,我在想,是不是把DataSource再用一个单例类来管理,形成一个双精度的单例模式是不是应该要更好一些阿
11 楼 抛出异常的爱 2006-11-29  
static ds
10 楼 unifly 2006-11-29  
DataSource是一个工厂,每次获取都要创建N个Connection,而你每次getConnection都返回一个新的DataSource,结果可想而知……
9 楼 deafwolf 2006-11-20  
请楼主自己google一下连接池吧
8 楼 John_wu 2006-11-19  
那为什么多个DataSource会造成占用大量连接呢,每个创建的连接不是都在方法结束的时候关闭连接了吗?而且deafwolf提到这样会失去DS的意义,又是什么原因呢,难道说DataSource的存在就一定应该是单态的吗?
7 楼 deafwolf 2006-11-19  
抱歉,我没从你的代码中看出单态的所在
对于公用的连接类,单态的应该是类里的DS,而不是对这个类加锁

public class ConnManager{
  private static DataSource dataSource=null;
  private ConnManager(){};
  private static Connection getConnection(){
    if(dataSource==null){
      dataSource=...;
    }
    return dataSource.getConnection();
  }
}

6 楼 John_wu 2006-11-19  
deafwolf 写道
别怪别人不帮你,这Db_sql和ConnManager应该是一个类吧?

初步判断,DataSource重复创建,占用了大量连接,并且失去了DS的意义
非常感谢deafwolf的回复,呵呵,我是有些心急了,因为这是一个已经上线了的项目,每次出问题后果都很严重,望见谅。Db_sql和ConnManager的确是同一个类,但是这个类我使用了单例模式,应该不会重复创建DataSource吧。
5 楼 deafwolf 2006-11-19  
别怪别人不帮你,这Db_sql和ConnManager应该是一个类吧?

初步判断,DataSource重复创建,占用了大量连接,并且失去了DS的意义
4 楼 John_wu 2006-11-19  
帖出来已经1天了,只有人浏览,没有人回复,不知道是大家都不知道怎么解决,还是觉得问题太简单不屑于回答,又或是不原意帮助一个论坛的新人,反正比起刚开始发现这论坛时候的兴奋,现在已经是心灰意冷了!
3 楼 John_wu 2006-11-18  
public class ConnManager {

	  /***
	   *通过一个对象锁来控制数据库连接的同步
	   */
	 public static Object lock=new Object();
	 /**
	  *
	  */
	 public static ConnManager connManager=null;
	 /**   * 这个数据库连接成员只有在与数据库直接建立连接的情况下是有效的   */

	  private Connection conn = null;

	 /**   * 当这个参数有效时,表明程序是从连接池里取得连接。   */
	 private String datasource;
	 private ConnManager(){
	 }
	 /**
	  *
	  * @return single instance
	  */
	 public static ConnManager getInstance(){
	   if(connManager==null){
	     synchronized (lock) {
	        if(connManager==null){
	        	connManager=new ConnManager();
	        }
	     }
	   }
	   return connManager;
	 }

	 /*连接池类型 type:0--DBCP、C3P0等;1--proxool;2--Weblogic*/
	 public Connection getConnection(String datasource,int type) throws Exception {
		 DataSource ds = getDataSource(datasource,type);
		 try {
			 if(type!=1)
				 conn=ds.getConnection(); //每调用一次都返回一个连接池中的数据库连接
			 else{
				 Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
                 conn=DriverManager.getConnection("proxool."+datasource);
			 }
		 }catch(Exception dsex){
			 dsex.printStackTrace();
			 throw dsex;
		 }
		 return conn;
	 }
	 
	 private DataSource getDataSource(String datasource,int type)throws Exception{
		 DataSource ds =null;
		 if(type!=0&&type!=1&&type!=2){
			 throw new Exception("输入的连接池类型不存在:"+type);
		 }
		 else if(type==0){
			Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            ds = (DataSource) envCtx.lookup(datasource);
		 }
		 else if(type==2){
			Properties properties =  new Properties();
            properties.put(Context.INITIAL_CONTEXT_FACTORY,
                           "weblogic.jndi.WLInitialContextFactory");
            //properties.put(Context.PROVIDER_URL, "t3://127.0.0.1:7001");
        	Context ctx = new InitialContext(properties);
        	ds = (javax.sql.DataSource) ctx.lookup (datasource);
		 }
		 return ds;
	 }
	 
	  /**   * 释放连接,从连接池中取得的连接那么释放传来的连接   * @param conn
	   */
	  public void disConnect(Connection connection) throws Exception {
	      try {
	        if (connection != null) {
	           connection.close();
	        }
	      }catch (Exception ex) {
	        throw ex;
	      }
	  }

}
2 楼 John_wu 2006-11-18  
第一次发帖,不知道用上面的“Code”键,重新发一下代码:
/**
	     * 获取数据库连接
	     * @throws Exception
	     * @return boolean
	     */
	    public Connection connect() throws Exception{
	         Connection conn = null;
	         if(connType!=0&&connType!=1&&connType!=2)
	        	 throw new Exception("您输入的数据库连接类型"+connType+"不存在");
	         try{
        		 Db_sql cm=Db_sql.getInstance();
                 conn = cm.getConnection(dbname,connType);
	         }catch(Exception e){
	            logger.info("取得数据连接失败:");
	            e.printStackTrace();
	            throw e;
	         }
	         return conn;
	     }
	    

	    /**
	   * @function close
	   * @throws Exception
	   */
	  private void closeConn(Connection conn){
		  try{
			  Db_sql.getInstance().disConnect(conn);
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
	  
	  private void closeStatm(Statement statm){
		  try{
			  if(statm!=null){
				  statm.close();
			  }
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
	  
	  private void closeResult(ResultSet rs){
		  try{
			  if(rs!=null){
				  rs.close();
			  }
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
public List executeQuery(String sql) throws Exception{
	    	Connection conn=null;
	        Statement stmt = null;
	        ResultSet result=null;
	        List list = new ArrayList();
	        //logger.info("sql:"+sql);
	        try{
	        	conn=this.connect();
	        	stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
	    		if(result != null){
	    			result.close();
	    			result = null;
	    		}
	    		if(stmt==null) System.err.println("statement is null");
	    		result = stmt.executeQuery(sql);
	          ResultSetMetaData rsmd = result.getMetaData();
	          while ( result.next() ){
	            Map map = new HashMap();
	            for ( int i = 1; i <= rsmd.getColumnCount(); i++ ){
	              map.put(rsmd.getColumnName(i), result.getObject(i));
	              //System.out.println("name----"+rsmd.getColumnName(i));
	            }
	            list.add(map);
	          }
	        }
	        catch ( Exception e ){
	     	 logger.info("sql:"+sql);
	          e.printStackTrace();
	        }
	        finally{
	            closeResult(result);
	            closeStatm(stmt);
	            closeConn(conn);
	        }
	        return list;
	     }
1 楼 John_wu 2006-11-18  
而且之前不还试过Tomcat5.0+DBCP、Tomcat5.0+C3P0、Tomcat5.0+proxool、Weblogic+proxool,都有连接部不能正常释放的问题,我现在想用Tomcat5.5.2+proxool,不知道会不会好一些

相关推荐

    连接池案例 连接池案例

    1. C3P0:开源的JDBC连接池,提供了强大的异常处理机制和丰富的配置选项。 2. DBCP (Apache BasicDataSource):Apache的数据库连接池,基于Jakarta-pool,相对简单易用。 3. HikariCP:高性能的连接池,设计目标是...

    java + SQL数据库连接池!!!!!!!!!!!!!

    数据库连接池在Java和SQL应用中扮演着至关重要的角色,它是优化数据库操作性能、提高系统资源利用率的关键技术。本文将深入探讨Java与SQL数据库连接池的概念、工作原理、优势以及如何在实际项目中进行配置和使用。 ...

    kafka生产者连接池

    3. **连接池管理**:连接池需要监控连接的状态,确保连接的有效性,当检测到连接异常时,会自动移除并重新创建新的连接。 4. **连接扩展**:当连接池中的连接被全部占用时,如果请求量持续增加,连接池可能会根据...

    java ftp连接池

    Java FTP连接池是一种用于管理FTP(文件传输协议)连接的资源池,它的主要目标是提高应用程序的性能和效率。在传统的FTP操作中,每次需要连接到FTP服务器时都会创建一个新的连接,这会消耗大量时间和系统资源。而...

    连接池源码和视频教程

    - C3P0:这是一个开源的JDBC连接池,提供了比DBCP更好的性能和更完善的异常处理。C3P0允许设置各种参数来控制连接池的行为,如最小连接数、最大连接数等。 - DBCP(DBCP2):Apache基础库提供的连接池实现,相对...

    基于Java的数据库连接池组件

    需要注意的是,要确保在操作发生异常时也能够正确释放连接。 编程实践: 使用连接池时,需要关注数据库连接的正确管理和资源的有效使用。例如,避免持有连接不释放,导致连接池耗尽;同时也要防止使用完连接后不...

    数据库连接池的实现(java版本)

    2. **连接获取与释放**:应用程序通过调用连接池的方法来获取连接,使用完毕后应释放连接,使其返回连接池以便后续重用。 3. **连接管理**:连接池会管理连接的状态,确保连接的有效性,比如通过测试表来验证连接...

    C# 数据库连接池 C# 数据库连接池

    1. **使用using语句**:即使连接池会管理连接,也应使用`using`语句来确保在操作完成后正确地释放资源。 2. **适当设置连接池大小**:根据应用的并发用户量和数据库负载,合理设置最小和最大连接数。 3. **及时...

    Java 连接池源码

    连接池的基本思想是预先创建一定数量的数据库连接,并将它们保存在一个池中,当应用需要时可以从池中获取一个连接,使用完毕后再归还到池中,而不是每次用完就关闭连接。这样避免了频繁地创建和销毁连接,降低了系统...

    连接池 连接池连接池 连接池

    在JSP中使用连接池,通常是在Servlet或者Filter中初始化连接池,然后在需要访问数据库的JSP页面或Servlet中获取和释放连接。这种方式使得数据库连接的管理更加规范,降低了资源消耗。 连接池的使用还有以下几个重要...

    socket 客户端连接池实现

    Socket客户端连接池是一种在分布式系统或网络编程中提高性能和效率的重要技术。它允许应用程序预先创建并维护一组可重用的Socket连接,从而避免了每次通信时建立新连接的开销。本文将深入探讨Socket客户端连接池的...

    数据库连接池的工作原理

    - **C3P0**:开源的JDBC连接池,提供异常检测、连接测试等功能。 - **HikariCP**:高性能的连接池,设计目标是提供最低的延迟和最佳的性能。 - **DBCP**:Apache提供的基础连接池实现,简单易用但性能一般。 - *...

    okhttp中连接池实现

    本文将深入探讨OkHttp中的连接池实现,包括连接对象的添加、移除机制以及其工作原理。 首先,我们需要了解什么是连接池。连接池是一种资源管理技术,用于存储和管理预先建立的网络连接,避免每次请求都创建新的TCP...

    mysql连接池java源码

    - **释放连接**:操作完成后,应用将连接返回给连接池,而不是直接关闭。 - **回收与销毁**:连接池会定期检查并回收超时或异常的连接,当连接池不再需要时,会销毁所有连接。 5. **关键设计点** - **线程安全**...

    手动设计自定义数据库连接池

    4. **异常处理与连接监控**:连接池还需要处理各种异常情况,例如连接超时、无效连接等。同时,还需要提供监控功能,便于了解连接池的状态。 #### 四、自定义数据库连接池的设计考量 在设计自定义数据库连接池时,...

    数据库的连接池原理,基本概念及原理,服务器自带的连接池

    * 连接池的分配与释放:连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。 * 连接池的配置与维护:连接池中...

    连接池配置文件

    4. 连接超时(Connection Timeout):应用程序尝试从连接池获取连接,但如果没有可用连接,等待超时后将抛出异常。合理设置可以避免应用程序长时间等待。 5. 静止时间(Idle Timeout):连接在池中未被使用的最长...

    MySql数据库连接池C#代码(有注释含测试代码)

    - 监控和日志:监控连接池的使用情况,记录异常,便于调试和优化。 总的来说,这个代码示例提供了一个基础的MySQL数据库连接池实现,可以作为学习和开发的起点。然而,正如描述中提到的,代码可能存在优化空间,...

Global site tag (gtag.js) - Google Analytics