ConnectionPool을 새로 만들어봤습니다.
1. MySql용입니다.
2. timeout, db-server reset 등으로 DB 와 연결을 잃었을 때
좀비가 되는 문제를 해결하였습니다.
3. ConnectionPool클래스를 web.xml에 Listener로 등록하고 getConnection()메소드를
static 으로 만들어 어디서든지 풀에 접근가능하도록 하였습니다.
4. Connection반환은 필수입니다. 저는 ConnectionPool에 접근하는 중간계층의 클래스
를 만들어 사용하기 때문에 풀자체에서 반환여부를 체크하지 않습니다.
5. web.xml 설정예제 : context-param 을 이용해 풀에 필요한 정보를 전달합니다.
context-param 과 listener 의 위치에 주의하십시요.
<web-app>
<display-name></display-name>
<description></description>
<context-param>
<param-name>database</param-name>
<param-value>#dbname#</param-value>
</context-param>
<context-param>
<param-name>database_user</param-name>
<param-value>#user-name#</param-value>
</context-param>
<context-param>
<param-name>database_password</param-name>
<param-value>#password#</param-value>
</context-param>
<context-param>
<param-name>database_min</param-name>
<param-value>3</param-value>
</context-param>
<context-param>
<param-name>database_max</param-name>
<param-value>10</param-value>
</context-param>
<!--
<filter>..</filter>
<filter-mapping>..</filter-mapping>
-->
<listener><listener-class>kr.co.korm.sql.ConnectionPool</listener-class></listener>
<!--기타 태그들 -->
</web-app>
---------------------------------------------------------------------------------------------------
/* Copyright (C) www.korm.co.kr 박정규 본 프로그램은 공개소프트입니다. 여러분은 이 프로그램을 마음껏 수정하시고 배포하실수 있읍니다. 여러분에게 도움이 되는 프로그램이기를 바랍니다. 최종수정일 2003년 6월 29일 */ package kr.co.korm.sql; import java.util.Vector; import java.sql.*; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContext; public class ConnectionPool implements ServletContextListener { static Vector connections = new Vector(); static String url="jdbc:mysql://localhost:3306/#database#?autoReconnect=true&useUnicode=true&characterEncoding=euc-kr"; static String user = null; static String passwd = null; static int max = 1; static int min = 1; private ServletContext context = null; /** * Context 가 시작되었을 때 호출된다. */ public void contextInitialized(ServletContextEvent event) { context = event.getServletContext(); String database = context.getInitParameter("database"); url = url.replaceAll("#database#", database); user = context.getInitParameter("database_user"); passwd = context.getInitParameter("database_password"); try { min = Integer.parseInt(context.getInitParameter("database_min")); } catch(Exception e){} try { max = Integer.parseInt(context.getInitParameter("database_max")); } catch(Exception e) {} try { Class.forName("org.gjt.mm.mysql.Driver"); // 최소수만큼의 연결을 생성해놓는다. for(int i=0;i<min;i++) { connections.add( DriverManager.getConnection(url, user, passwd) ); } } catch(Exception e) { context.log(e.getMessage()); } } /** * Context 가 종료될때 호출된다. */ public void contextDestroyed(ServletContextEvent event) { for(int i=0;i<connections.size();i++) { Connection con = (Connection)connections.elementAt(i); try { con.close(); } catch(Exception e){} } connections.clear(); } /** * 풀로부터 Connection 객체를 얻는 함수 */ public static Connection getConnection() throws Exception { Connection con = null; int try_count=0; while(true) { try { return (Connection)connections.remove(0); } catch(Exception e){} // 모든 Connection이 사용중이면 Excetion이 발생한다. try { return DriverManager.getConnection(url, user, passwd); } catch(Exception e){} // 더 이상 데이타베이스서버로부터 Connection을 가져올 수 없으면 Exception발생 if(try_count++>3) throw new ConnectionException("일시적으로 사용자가 너무 많아 데이타베이스에 연결할 수 없습니다."); try { Thread.sleep(50); } catch(Exception e){} //0.05초 후에 재시도한다. } } /** * 풀에 Connection 객체를 반납한다. */ public static void free(Connection con) { try { if(connections.size() < max) connections.add(con); else con.close(); } catch(Exception e){} } }
'프로그래밍 > Web' 카테고리의 다른 글
01 로그인.... (0) | 2007.11.28 |
---|---|
[펌] Filter 를 이용한 한글 인코딩 적용 (0) | 2007.11.27 |
밑의 에러 페이지 처리에 이어서. (0) | 2007.11.27 |
에러 페이지 처리 (0) | 2007.11.27 |
열혈강의 6장 실습하기 (0) | 2007.11.27 |