context-param

프로그래밍/Web 2007. 11. 27. 15:17 Posted by galad

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