2012-12-06 2 views
2

내 응용 프로그램이 최대 절전 모드 4.1.7 및 c3p0 0.9.1을 사용 중입니다.설정에서 지정된 것보다 많은 연결을 생성하는 c3p0

내 응용 프로그램의 hibernate.cfg.xml 파일에 c3p0.max_size 속성을 50으로 설정했지만 생성 된 JDBC 연결 수가이 값을 초과했습니다. 또한 휴면/유휴 연결은 Hibernate 구성에서도 지정 했으므로 제거되지 않습니다. 내 구성에서 잘라내 기는 다음과 같습니다.

<property name="c3p0.acquire_increment">1</property> 
<property name="c3p0.autoCommitOnClose">false</property> 
<property name="c3p0.max_size">50</property> 
<property name="c3p0.min_size">1</property> 
<property name="c3p0.numHelperThreads">1</property> 
<property name="c3p0.maxIdleTime">30</property> 
<property name="c3p0.maxIdleTimeExcessConnections">20</property> 
<property name="c3p0.maxConnectionAge">45</property> 

내 코드에서 finally 블록의 세션과 세션 팩토리를 명시 적으로 닫고 있습니다. 나는 로그를 변경

public static int insert(int aidm, String termCode, String wappCode) throws SQLException, ClassNotFoundException {  
     // Initialize session and transaction 
     SessionFactory sessionFactory = HibernateSessionFactory.create(); 
     Session session = sessionFactory.openSession(); 
     Transaction tx = null; 
     int applSeqno = 0; 
     Stvwapp wapp = null; 

     try { 
      tx = session.beginTransaction(); 

      applSeqno = generateApplSeqNo(session, aidm); 
      SarheadId sarheadIdDao = new SarheadId(); 
      sarheadIdDao.setSarheadAidm(aidm); 
      sarheadIdDao.setSarheadApplSeqno((short)applSeqno); 

      // Find STVWAPP row by WAPP code 
      Query query = session.getNamedQuery("findStvwappByWappCode"); 
      query.setString("wappCode", wappCode); 

      if (query.list().size() == 0) { 
       throw new RuntimeException("Invalid WAPP code specified: " + wappCode); 
      } else { 
       wapp = (Stvwapp) query.list().get(0); 
      } 

      Sarhead sarheadDao = new Sarhead(); 
      sarheadDao.setId(sarheadIdDao); 
      sarheadDao.setSarheadActivityDate(new java.sql.Timestamp(System.currentTimeMillis())); 
      sarheadDao.setSarheadAddDate(new java.sql.Timestamp(System.currentTimeMillis())); 
      sarheadDao.setSarheadAplsCode("WEB"); 
      sarheadDao.setSarheadApplAcceptInd("N"); 
      sarheadDao.setSarheadApplCompInd("N"); 
      sarheadDao.setSarheadApplStatusInd("N"); 
      sarheadDao.setSarheadPersStatusInd("N"); 
      sarheadDao.setSarheadProcessInd("N"); 
      sarheadDao.setSarheadTermCodeEntry(termCode); 
      sarheadDao.setStvwapp(wapp); 

      session.save(sarheadDao); 
     } finally { 
      tx.commit(); 
      session.close(); 
      sessionFactory.close(); 
     } 

     return applSeqno; 
    } 

업데이트 :

package ics.sis.util; 

import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.service.ServiceRegistry; 
import org.hibernate.service.ServiceRegistryBuilder; 

import ics.global.runtime.Environment; 
import ics.util.properties.PropertiesISUWrapper; 

public class HibernateSessionFactory { 
    private static SessionFactory sessionFactory; 
    private static ServiceRegistry serviceRegistry; 
    private static final PropertiesISUWrapper ISU_PROPERTIES = new PropertiesISUWrapper(Environment.getName(),"VzAppIntegration"); 

    public static SessionFactory create() { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 

     configuration.setProperty("hibernate.connection.url", ISU_PROPERTIES.getUrl()); 
     configuration.setProperty("hibernate.connection.password", ISU_PROPERTIES.getPassword()); 

     serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();   
     sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
     return sessionFactory; 
    } 

} 

여기 데이터베이스 트랜잭션을 수행하는 주요 방법 중 하나입니다 : 여기 내 SessionFactory에 인스턴스를 생성하기 위해 사용하고 클래스이다 연결 풀링에 대한 자세한 로깅을 얻으려면 c3p0의 수준을 DEBUG로 설정하고 만료 된 연결마다 3 ~ 4 초마다 확인합니다. 또한, 나는 수영장에 총 두 개의 연결이있는 것처럼 보이는 다음 줄이 기록되는 것을보고있다. 그러나 Toad에서는 열려있는 총 JDBC 연결을 모니터링하고 있으며이를 보여줍니다. 그래서이 숫자 사이에 왜 불일치가 있는지를 파악하려고합니다.

[봉투 : DEVL] [] - 2012년 12월 6일 12시 14분 7초 디버그 BasicResourcePool : 1,644 - 관리 추적 [email protected] [: 1, 미사용 : 1, 제외 : 0] (예 : [email protected])

답변

0

문제는 응용 프로그램 시작시 한 번만 호출해야했지만 문제는 응용 프로그램 내에서 새로운 세션 팩토리를 여러 번 만드는 것이 었습니다. ServletContextListener 인터페이스를 구현 한 클래스를 생성하여 새로운 세션 팩토리를 생성하고 컨텍스트가 파손되었을 때이를 폐기하거나 닫습니다.

+1

그게 내가 대답했다. P : P –

7

당신은 그 말 :

나는 c3p0.max_size의 속성을 설정 한 내 응용 프로그램에 대한 내 hibernate.cfg.xml 파일은 50이지만 JDBC conn의 수 생성 된 활동이 그 가치를 초과했습니다.

insert 메서드에서 create() 메서드를 호출하기 때문에 이러한 현상이 발생합니다.

configuration.buildSessionFactory(serviceRegistry); 

을 그 방법으로 당신은 또한 sessionFactory을 닫습니다 : 당신의 create() 방법 때마다, 당신은이 같은 새로운 SessionFactory를 구축 할 수 있습니다. sessionFactory 인스턴스를 생성하고 닫는 작업은 모두 매우 비용이 많이 드는 작업입니다 (닫기 메서드 here 참조).

무엇보다도 응용 프로그램이 여러 스레드에서 여러 요청을 동시에 처리 할 때 각 스레드는 고유 한 sessionFactory (각각 자체 풀을 생성 함)를 만듭니다. 따라서 한 번에 여러 개의 sessionFactory 및 Connection 풀이 시스템에 존재합니다. 반면 응용 프로그램의 수명 동안 한 번만 만들어야합니다. 여러 개의 풀 복사본이있는 경우 모든 풀의 총 연결 수는 최대 한도를 초과 할 수 있으므로 하나의 풀에 대해 구성했습니다.

나는 당신이 우는 소리처럼 HibernateSessionFactory 클래스를 재 작성하는 것이 좋습니다 것입니다 :

public class HibernateSessionFactory { 
    private static SessionFactory sessionFactory = HibernateSessionFactory.create(); 
    private static ServiceRegistry serviceRegistry; 
    private static final PropertiesISUWrapper ISU_PROPERTIES = new PropertiesISUWrapper(Environment.getName(),"VzAppIntegration"); 

    private static SessionFactory create() { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 

     configuration.setProperty("hibernate.connection.url", ISU_PROPERTIES.getUrl()); 
     configuration.setProperty("hibernate.connection.password", ISU_PROPERTIES.getPassword()); 

     serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();   
     return configuration.buildSessionFactory(serviceRegistry); 

    } 

    public static SessionFactory getSessionFactory(){ 
     return sessionFactory; 
    } 

} 

insert() 방법 대신 HibernateSessionFactory.create()를 호출에

는, 단순히 HibernateSessionFactory.getSessionFactory()를 호출합니다.

+0

해당 속성을 추가하고 30 초로 설정하고 idleTime 것들을 제거했습니다. 그러나 JDBC 커넥션의 수가 데이터베이스에서 증가 할 때, 그들은 줄어들지 않고, 많은 것들이 남아 있습니다. 기존의 유휴 상태의 풀이있을 때 풀이 계속 더 많은 연결을 생성하는 이유를 알 수 없습니다. – Brian

+0

설명서에 따르면 c3p0.timeout은 c3p0.maxIdleTime과 동일한 속성이라고 생각합니다. – Brian

+0

연결 수가 최대 풀 크기를 초과합니까? –

관련 문제