2014-11-05 2 views
2

내 응용 프로그램과 응용 프로그램 서버 jbossAS7에서 Struts2, Spring3 및 Hibernate4를 사용하고 있습니다. 문제는 연결 풀의 최대 한도를 20으로 설정 한 것입니다. 20 명의 사용자가 응용 프로그램에 접속하면 관리 연결을 가져올 수 없음 예외가 발생합니다. 사용자 당 2 개의 연결로 10 명의 사용자 만 20 개의 모든 연결을 사용하고 있습니다. 왜 그런 일이 일어나는거야?JDBC 연결 릴리스 이슈

<bean id="transactionManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
<property name="dataSource" ref="dataSource" /> 
<property name="sessionFactory" ref="sessionFactory"/> 
</bean> 
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">  
<property name="transactionManager" ref="transactionManager"/> 
<property name="transactionAttributes"> 
<props> 
<prop key="insert*">PROPAGATION_REQUIRED,-java.lang.Exception</prop> 
</props> 
</property> 
</bean> 

<bean id="loginDTO" class="com.tcs.oss.tims.loginManagement.dto.LoginDTO" /> 

<bean id="loginAction" class="com.tcs.oss.tims.loginManagement.action.LoginAction" scope="prototype"> 
<property name="loginDAO" ref="loginDAO" /> 
<property name="loginDTO" ref="loginDTO" /> 
<property name="roleBasedAction" ref="roleBasedAction"></property> 
</bean> 

<bean id="loginDAOImpl" class="com.tcs.oss.tims.loginManagement.dao.daoImpl.LoginDAOImpl" scope="prototype"> 
<property name="sessionfactory" ref="sessionFactory" /> 
</bean> 

<bean id="loginDAO"parent="baseTransactionProxy" scope="prototype"> 
<property name="target"> <ref bean="loginDAOImpl"/> </property> 
</bean> 

최대 절전 모드 설정 : 아래

은 제이보스 standalone.xml

<datasource jta="false" jndi-name="java:/comp/env/jdbc/DB_NAME" pool-name="DB_POOL" enabled="true" use-java-context="true" use-ccm="false"> 
<connection-url>jdbc:log4jdbc:postgresql://localhost:5432/test_db</connection-url> 
<driver-class>net.sf.log4jdbc.sql.jdbcapi.DriverSpy</driver-class> 
<driver>log4jdbc</driver> 
<pool> 
<min-pool-size>2</min-pool-size> 
<max-pool-size>20</max-pool-size> 
</pool> 
<security> 
<user-name>postgres</user-name> 
<password>postgres</password> 
</security> 
<validation> 
<validate-on-match>false</validate-on-match> 
<background-validation>false</background-validation> 
</validation> 
<statement> 
<prepared-statement-cache-size>0</prepared-statement-cache-size> 
<share-prepared-statements>false</share-prepared-statements> 
</statement> 
</datasource> 

봄 트랜잭션 관리 프로그램 구성에서 데이터 소스의 구성입니다

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
<property name="dataSource"> 
<ref bean="dataSource" /> 
</property> 

<property name="hibernateProperties"> 
<props> 
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> 
<prop key="hibernate.show_sql">true</prop>  
<prop key="hibernate.cache.use_second_level_cache">true</prop> 
<prop key="hibernate.cache.use_query_cache">true</prop> 
<prop key="hibernate.generate_statistics">true</prop> 
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop> 
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> 
</props> 
</bean> 

데이터 소스 구성 :

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="java:/comp/env/jdbc/TIMS_DB"/> 
</bean> 

샘플 코드 :

public void insertIntoInstance(String id) throws Exception { 
try { 
Session session = sessionfactory.getCurrentSession(); // Where the sessionfactory is from Dependency Injection 
Query insertQry = session.createSQLQuery("insert into table(id)values(id)"); 
insertQry.executeUpdate(); 
} catch (Exception e) { 
throw e; 
} 
} 

의 web.xml :

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" id="WebApp_9" version="2.4"> 

    <context-param> 
<param-name>contextConfigLocation</param-name> 
<param-value>/WEB-INF/classes/SpringBeans.xml</param-value> 
    </context-param> 

    <servlet> 
<servlet-name>InitializerServlet</servlet-name> 
<servlet-class>com.tcs.oss.tims.utilities.InitializerServlet</servlet-class> 
<load-on-startup>1</load-on-startup> 
</servlet> 

    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

<filter-mapping> 
<filter-name>CASFilter</filter-name> 
<url-pattern>/General/*</url-pattern> 
</filter-mapping> 
    <filter> 
<filter-name>CASFilter</filter-name> 
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class> 
<init-param> 
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name> 
<param-value>${CAS_LOGIN_URL}</param-value> 
</init-param> 
<init-param> 
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name> 
<param-value>${CAS_PROXY_VALIDATE_URL}</param-value> 
</init-param> 
<init-param> 
    <param-name>edu.yale.its.tp.cas.client.filter.serviceUrl</param-name> 
     <param-value>${LOGIN_URL}</param-value> 
</init-param> 
<init-param> 
<param-name>edu.yale.its.tp.cas.client.filter.wrapRequest</param-name> 
<param-value>true</param-value> 
</init-param> 
</filter> 

<filter> 
    <filter-name>struts2</filter-name> 
    <filter-class> 
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 
     </filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>struts2</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

</web-app> 

내가 연결이 스프링 트랜잭션 관리자에 의해 관리하는 방법을 모르겠어요. 최대 절전 모드의 경우 연결 해제 모드가 있습니다. 트랜잭션 이후에는 연결을 해제 할 수 있지만 스프링 트랜잭션이있을 때 작동하지 않는 것 같습니다. 도와주세요.

+0

은 아마 당신의 설정이 잘못 봄 JTA 송신 관리자를 구성하는 것을 잊지 마세요. 왜'org.hibernate.Transaction.JDBCTransaction' 클래스는 Spring의'HibernateTransactionManager'를 사용하지 않는 것입니까? 또한 왜 당신은 여전히 ​​트랜잭션 구동 형 또는 aspect 형 트랜잭션 대신에 고대의'TransactionProxyFactoryBean'을 사용하고 있습니다 (많은 구성을 절약 할 수 있습니다). 다음으로 연결과 세션을 직접 열지 말고 ('openSession'을 사용하지 말고'getCurrentSession'을 사용하십시오) 빈을 복제하지 않는지 확인하십시오. –

+0

죄송합니다. 실수였습니다. 내가 사용하고있는 것을 업데이트했습니다. 그리고 getCurrentSession을 사용하고 있습니다. 어떤 설정이 잘못되었을 수 있습니까? 그것에 대해 명확하지 않습니다. – Develope001

+0

데이터 소스 구성 (스프링)을 게시하고 코드를 표시하십시오. 또한 명시된 바와 같이 트랜잭션을 발생시키는 고대의 방법을 사용하고 있다면 새로운 트랜잭션 방식으로 마이그레이션하는 것을 고려해야합니다. –

답변

0

이런 종류의 환경에서 JTA 트랜잭션 관리자를 사용해야합니다.

완전한 응용 프로그램 서버를 사용하고 있으므로 이미 (jta = "true"로 설정 한 경우) 설치 한 데이터 소스와 통합 된 트랜잭션 관리자가 내장되어 있습니다. 또한 다음을 사용하십시오 :

<prop key="hibernate.transaction.jta.platform"> 
    org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform 
</prop> 
<prop key="hibernate.transaction.factory_class"> 
    org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory 
</prop> 

트랜잭션이 커밋되고 관련 데이터베이스 연결을 해제 할 때 최대 절전 모드 세션이 자동으로 닫혀 야합니다.

그리고

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> 
+0

그럼에도 트랜잭션을 처리하지 않겠습니까? 연결이 해제되거나 닫히는 시점을 어떻게 추적합니까? 이 관점에서 JTA의 이점은 무엇입니까? 너는 말해 줄 수 있니? – Develope001