복붙노트

[SPRING] Spring과 DBCP로 JDBC 커넥션을 처리하는 적절한 방법은 무엇입니까?

SPRING

Spring과 DBCP로 JDBC 커넥션을 처리하는 적절한 방법은 무엇입니까?

스프링 MVC를 사용하여 SQL Server 데이터베이스 위에 얇은 레이어를 만듭니다. 테스트를 시작했을 때 스트레스를 잘 처리하지 못하는 것 같습니다. :) 연결 풀링과 데이터 소스를 처리하기 위해 Apache Commons DBCP를 사용하고 있습니다.

처음 ~ 10-15 개의 동시 연결을 시도했을 때 서버가 멈추고 서버를 다시 시작해야했습니다. (dev는 Tomcat을 사용하고 있지만 결국 Weblogic에 배포해야합니다).

다음은 Spring bean 정의이다.

<bean id="dataSource" destroy-method="close"
      class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
    <property name="url" value="[...]"/>
    <property name="username" value="[...]" />
    <property name="password" value="[...]" />
</bean>

<bean id="partnerDAO" class="com.hp.gpl.JdbcPartnerDAO">
    <constructor-arg ref="dataSource"/>
</bean>

<!-- + other beans -->

그리고 이것이 제가 사용하는 방법입니다 :

// in the DAO
public JdbcPartnerDAO(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
}

// in the controller
@Autowired
private PartnerDAO partnerDAO;

// in the controller method
Collection<Partner> partners = partnerDAO.getPartners(...);

약간 읽은 후에, (GenericObjectPool에서) BasicDataSource에 대한 maxWait, maxActive 및 maxIdle 속성을 찾았습니다. 여기에 문제가 온다. 나는 그것을 어떻게 설정해야하는지 잘 모르겠다. 내가 아는 바로는, Spring은 내 연결을 관리해야하므로, 나는 그 연결 해제에 대해 걱정할 필요가 없습니다.

<bean id="dataSource" destroy-method="close"
      class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
    <property name="url" value="[...]"/>
    <property name="username" value="[...]" />
    <property name="password" value="[...]" />
    <property name="maxWait" value="30" />
    <property name="maxIdle" value="-1" />
    <property name="maxActive" value="-1" />
</bean>

먼저 풀에서 사용할 수있는 연결이 없을 때 예외가 발생하지 않도록 maxWait을 설정합니다. 예외 메시지는 다음과 같습니다.

일부 장기 실행 쿼리가 있지만 쿼리 복잡성에 관계없이 예외가 발생했습니다.

그런 다음 maxActive와 maxIdle을 설정하여 처음부터 예외를 throw하지 않도록합니다. maxActive와 maxIdle에 대한 기본값은 8입니다 (이유를 모르겠습니다). -1로 설정하면 더 이상 예외가 발생하지 않으며 모든 것이 잘 작동하는 것처럼 보입니다.

이 앱이 많은 수의 동시 요청을 지원해야한다는 것을 고려하면이 설정을 무한대로 두어도 괜찮습니까? Spring이 실제로받은 연결을 관리 할 것인가? 죽은 줄 알았는데 C3P0으로 전환해야합니까?

해결법

  1. ==============================

    1.이미 알고있는 것처럼 기본 dbcp 연결 풀은 8 개의 연결이므로 9 개의 동시 쿼리를 실행하려면 그 중 하나가 차단됩니다. 데이터베이스에 연결하고 exec sp_who2를 실행하면 연결된 대상과 활성 상태, 그리고 쿼리가 차단되는지 여부가 표시됩니다. 그런 다음 문제가 db 또는 코드에 있는지 확인할 수 있습니다.

    이미 알고있는 것처럼 기본 dbcp 연결 풀은 8 개의 연결이므로 9 개의 동시 쿼리를 실행하려면 그 중 하나가 차단됩니다. 데이터베이스에 연결하고 exec sp_who2를 실행하면 연결된 대상과 활성 상태, 그리고 쿼리가 차단되는지 여부가 표시됩니다. 그런 다음 문제가 db 또는 코드에 있는지 확인할 수 있습니다.

    Spring의 JdbcTemplate 객체 군을 사용하는 한 연결은 예상대로 관리되며, 원시 데이터 소스를 사용하려면 DataSourceUtils를 사용하여 Connection을 확보해야합니다.

    또 다른 제안 - Spring 3 이전에는 JdbcTemplate을 사용하지 않고 SimpleJdbcTemplate을 사용하고 SimpleJdbcTemplate.getJdbcOperations ()를 사용하여 동일한 메소드에 계속 액세스 할 수 있지만 generics를 사용하여 더 멋진 코드를 작성하고 필요성을 제거해야한다. JdbcTemplate / NamedParameterJdbcTemplate 인스턴스를 생성 할 수 있습니다.

  2. ==============================

    2.DBCP maxWait 매개 변수는 밀리 초 단위로 정의해야합니다. 30ms가 매우 낮 으면 30000ms로 늘려 다시 시도하십시오.

    DBCP maxWait 매개 변수는 밀리 초 단위로 정의해야합니다. 30ms가 매우 낮 으면 30000ms로 늘려 다시 시도하십시오.

  3. ==============================

    3.관점을 바꾸자.

    관점을 바꾸자.

    그것은 당신이 쿼리하고있는 테이블의 테이블이나 레코드가 (다른 활성 트랜잭션에 의해) 잠겨있어 시간이 초과 되었기 때문일 수 있습니다.

    SQL Server 클라이언트에서 동일한 쿼리를 실행 해보십시오. 오랜 시간이 걸릴 경우이 문제를 일으키는 테이블 또는 레코드 잠금인지 확인할 수 있습니다.

  4. from https://stackoverflow.com/questions/3525529/whats-the-proper-way-to-handle-jdbc-connections-with-spring-and-dbcp by cc-by-sa and MIT license