dbcp pooling설정에 validationQuery적용

2018. 7. 11. 14:29 JAVA/DBCP,JNDI,JDBC

tomcat dbcp를 이용하여 검색데이터 추출할 때, mysql 사용. 

mysql wait_timeout 설정(기본값 28800 , 8시간) 에 의해 커넥션이 연결된 이후 해당 

커넥션의 close 없이 8시간이 지나면 해당 커넥션을 종료.


▶issue : 종료된 커넥션을 dbcp의 connection pool 에선 여전히 가지고 있는 상태.

이런 상황에서 DB 관련 프로그램이 호출되면 커넥션 관련 에러가 발생.

▶solution : java에서 DB를 사용하기 전에 해당 connection 이 정상적인지 검사를 하도록 하는 것.
이 옵션이 validationQuery.

<-bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"->
<-property name="driverClassName" value="${jdbc.driverClassName}"/->
<-property name="url" value="${jdbc.url}"/->
<-property name="username" value="${jdbc.username}"/->
<-property name="password" value="${jdbc.password}"/->
<-property name="validationQuery" value="select 1"/->
<-/bean->

<-Resource name="jdbc/livesearch" auth="Container"
type="javax.sql.DataSource"
maxActive="10" maxIdle="30" maxWait="10000"
username="${jdbc.username}" password="${jdbc.password}"
driverClassName="com.mysql.jdbc.Driver"
url="${jdbc.url}"
validationQuery="select 1"
/>

와 같이 사용하면 된다.

<참고>
오라클의 경우 : validationQuery="select 1 from dual"


출처 : blog.hoonie.net

전에 기록한 "DBCP의 validationQuery는 약인가? 독인가?"에서 validationQuery는 필수가 아니라고 했었다. 그렇다면 만약 DBCP에서 바라보고 있는 DB 서버가 어떠한 이유로 사용 불가 상태에 들어갔다가 다시 사용 가능해 진다면 validationQuery가 없어도 DBCP는 Connection Pool을 제대로 복구할까?

DBCP 공식 사이트에서 관련된 내용을 검색해 보니 DBCP는 검증기능을 사용하지 않는 경우에도 DB서버가 셧다운 되었다가 다시 기동되면 자동으로 새로운 Connection 객체들을 Pool에 로딩한다 한다. 

단, DBCP의 프러퍼티를 기본값으로 설정되어 있고, 사용하는 JDBC 드라이버가 select 등의 쿼리 실행시 발생하는 예외상황에 대해 SQLException을 제대로 보고한다는 전제하에 굳이 validationQuery를 사용하지 않아도 된다고 한다. 적어도 최근 버전의 DBCP에서는 validationQuery는 돌다리도 두드려보는 개념인것 같다. 

다음은 DBCP사이트의 Wiki(DBCP공식사이트) 에서 확인한 내용이다.

Q: Without using validation of connections (testOnBorrow = false, testOnReturn = false, timeBetweenEvictionRunsMillis = -1) and after shutdown and restarting the database again, it looks like the pool is cleaning its old connections by itself. So it turns out that we always have valid connections. How can you explain this and when is explicit validation necessary? 

A: During the connection activation (when borrowing a connection) the setAutoCommit and other connection init methods are called. If one of these methods throws a SQLException then the connection is also considered broken and removed from the pool. 

So if you are using one of the "default*" properties and the JDBC driver correctly reports the SQLExceptions on the "set*" methods then you don't need an extra validationQuery.

참고 사이트 : Apache commons DBCP SITE