2017-03-05 1 views
0

각 웹 서비스 호출 후에 최대 연결 수를 유지합니다. EntityManager가 매번 생성되고 데이터베이스에 대한 새로운 연결을 생성하는 것처럼 보이지만 결코 연결을 완전히 닫거나 해제하지는 않습니다. 나는 항상 내 연결을 최대한 활용할 수 있으며 처음 호출 한 후에는 다시 연결하거나 쿼리를 실행할 수 없습니다.Hibernate JPA 너무 많은 연결

SessionManager/SessionFactory 또는 EntityManager를 사용하는 대신 사용할 필요가 있습니까?

정적 인 Connection cconn을 사용하지 않고 EntityManager과 연결을 유지 한 다음 마지막 블록에서 엠을 닫지 만 여전히 오류가 발생합니다. 나는 JPA를 처음 사용하므로 내 설계, 설정, 코드, 모든 것입니까? 연결을 얻기

- ConnectionUtil.java

public static Connection cconn = null; 

public static Connection conn(){ 

     try { 
      if(ConnectionUtil.cconn != null && !ConnectionUtil.cconn.isClosed()){ 
       return cconn; 
      } 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     Connection conn = null; 
     try { 
      String lcp = ConnectionUtil.getLcp(); 
      logging.info("LCP : " + lcp); 

      EntityManagerFactory factory = null; 
      Map<String,Object> prop = null; 

      String url ,password, user, connString; 

      // Set default Connection details 
      if(lcp == null){ 
       factory = Persistence.createEntityManagerFactory(LOCAL_PER); 
       prop = factory.getProperties(); 

       url = (String) prop.get("javax.persistence.jdbc.url"); 
       password = (String) prop.get("javax.persistence.jdbc.password"); 
       user = (String) prop.get("javax.persistence.jdbc.user"); 
       connString = url +"?user="+user+"&password="+password; 

       connString = "jdbc:mysql://localhost:3306/"+ConnectionUtil.DATABASE+"?" + "user=root&password=password"; 
       logging.info("Setting EntityManager to: default values"); 
       logging.info("Using string: "+ connString); 
       Properties properties = new Properties(); 
       properties.put("connectTimeout", "20000"); 
       conn = DriverManager.getConnection(connString,properties); 
       cconn = conn; 
      } 

persistance.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 

    <persistence-unit name="Hunting" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <properties> 
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database"/> 
      <property name="javax.persistence.jdbc.user" value="root"/> 
      <property name="javax.persistence.jdbc.password" value="password"/> 
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 


      <!-- Hibernate properties --> 
      <property name="hibernate.show_sql" value="false" /> 
      <property name="hibernate.format_sql" value="false" /> 
      <property name="hibernate.connection.release_mode" value="on_close" /> 
      <property name="hibernate.connection.pool_size" value="100" /> 


      <!-- Configuring Connection Pool --> 
      <property name="hibernate.c3p0.min_size" value="5" /> 
      <property name="hibernate.c3p0.max_size" value="20" /> 
      <property name="hibernate.c3p0.timeout" value="20" /> 
      <property name="hibernate.c3p0.max_statements" value="50" /> 
      <property name="hibernate.c3p0.idle_test_period" value="2000" /> 
     </properties> 
    </persistence-unit> 

내 웹 서비스의 기능에서 클럽 사용자를 얻기.

public static Club getClubById(long id){ 
     Club cc = new Club(); 
     EntityManager em = null; 
     try{ 
      em = ConnectionUtil.getEnitityManager(); 
      cc = em.find(Club.class, id); 
      cc.buildClubUsers(); 
     }finally{ 
      if(em != null){ 
       em.close(); 
      } 
     } 
     return cc; 
    } 

연결 오류

15:32:26.315 [http-bio-8080-exec-7] WARN org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator - HHH000022: c3p0 properties were encountered, but the org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider provider class was not found on the classpath; these properties are going to be ignored. 
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000402: Using Hibernate built-in connection pool (not for production use!) 
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 100 
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000006: Autocommit mode: true 
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/database] 
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000046: Connection properties: {user=root, password=password, autocommit=true, release_mode=on_close} 
15:32:26.315 [http-bio-8080-exec-7] DEBUG org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Opening new JDBC connection 
15:32:26.316 [http-bio-8080-exec-7] WARN org.hibernate.engine.jdbc.internal.JdbcServicesImpl - HHH000342: Could not obtain connection to query metadata : Data source rejected establishment of connection, message from server: "Too many connections" 

편집 : 1 추가 된 C3PO와 같은 "너무 많은 연결"오류가

Mar 05, 2017 3:46:17 PM com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask run 
WARNING: [email protected]9 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: 
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections" 
+0

각 비즈니스/저장소 사용 사례에 새로운 'EntityManagerFactory'를 작성하면 안됩니다. 이는 응용 프로그램에 아무런 이유없이 상당한 오버 헤드가 발생합니다. 일반적으로 응용 프로그램은 시작시'EntityManagerFactory' 또는'SessionFactory'를 생성하고 사용 사례에 필요한대로 각각 EntityManager 또는 Session 인스턴스를 생성하기 위해 팩토리를 재사용해야합니다. – Naros

답변

0

나는 당신의 용기에 의존하는 게 좋을 것하는 것은 할 수있어 귀하의 거래를 관리합니다. 다음의 대답에서 JPA 트랜잭션을 관리 할 수있는 웹 컨테이너를 사용하고 있다고 가정합니다. 대부분의 최첨단 기술이 가능합니다.

따라서, 당신은 당신의 persistance.xml 변경해야

<persistence-unit name="Hunting" transaction-type="JTA"> 

왜 JTA RESOURCE_LOCAL 이상? 간단히 말해서, 거래를 직접 관리 할 필요가 없습니다. https://stackoverflow.com/a/28998110/3507356

그런 다음 이 나는 현재 다음 클럽 수준의 적절한 현장 주석과 @Entity로 주석 가정

는 것 같아요 당신이 다음 제거 할 수 등

@PersistenceContext("Hunting") 
EntityManager em; 

public static Club getClubById(long id){ 
    Club cc = new Club(); 
    EntityManager em = null; 
    try{ 
     // em = ConnectionUtil.getEnitityManager(); 
     // EM is injected 
     cc = em.find(Club.class, id); 
     cc.buildClubUsers(); 
    }finally{ 
     if(em != null){ 
      em.close(); 
     } 
    } 
    return cc; 
} 
를 POJO 조정 ConnectionUtil은 웹 서비스에 Club-jpa-service를 주입하고 사용하기 만하면됩니다.

+0

나는 이것을 줄 것이다. 로컬 연결을 위해 로컬 응용 프로그램이 필요하므로 localhost와 QA/PR에 연결해야합니다. 아마존 aws에 연결해야합니다.시작할 때''Hunting "'또는''HuntingAmazon ''으로 @PersistenceContext ("Hunting ")'을 변경하거나 설정할 수 있습니까? – tiggles

+0

Persistence-unit-name을 변경하거나 동적으로 변경하는 것은 권장되지 않습니다. (비록 당신이 maven/ant-scripts로 할 수있다하더라도) 당신이 당신의 컨테이너에 의존한다면 - 당신의 컨테이너에 data-ressource를 정의하고 JNDI를 통해 이름을 정해야합니다. persistence.xml에서 액세스 자격 증명을 정의하는 부분이 서버 구성으로 이동하는 것이 좋습니다. 그런 다음'' jdbc/oracle''' 을 통해 데이터 소스를 명명/호출하십시오. 어떤 서버를 사용하고 있습니까? 특정 컨테이너에 대한 "JNDI Dataresource"조회. – The86Freak