본문으로 바로가기

[개발환경 ]

Spring-boot

Thymeleaf

MySQL

Eclipse IDE


Spring 으로 웹 개발을 하던 중 db connection 부분에 문제가 발생했다.

잘 되다가 어느 정도 사용하지 않고 시간이 조금 지난 뒤에 시도하면 발생한다.

로그를 확인하니 쿼리를 DB서버에 날릴 때 발생하는 에러인데, 상세한 로그는 다음과 같다.


java.sql.SQLNonTransientConnectionException: (conn=24377) Could not send query: Software caused connection abort: recv failed

at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:161)

at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:106)

at org.mariadb.jdbc.MariaDbStatement.executeExceptionEpilogue(MariaDbStatement.java:235)

at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:224)

at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:159)

at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.execute(PreparedStatementSpy.java:443)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

....

...


[원인]

구글링을 해 보니,

MySQL은 기본적으로 설정된 Timeout 시간이 있고, 해당 시간동안 사용되지 않은 Connection들에 대해서는 연결은 끊어버린다. 때문에 한동안 접속하지 않다가 스프링 서버에서 접속을 시도하면, DBCP는 연결이 끊어졌음을 모르기 때문에 커넥션 요청이 들어오면 연결이 끊긴 connection들을 반환하게 되고 에러가 발생한다.


[해결]

어플리케이션에 커넥션을 return하기 전에 dbcp가 테스트 쿼리를 날려서 커넥션이 살아있는지를 체크한다.

그 뒤 연결이 끊어졌으면 자동으로 다시 연결하고 본래 쿼리를 실행한다.


DBCP configuration에 아래를 추가한다.

- validationQuery="SELECT 1" (Oracle의 경우는 select 1 from dual)

- testOnBorrow="true" (실제 쿼리를 날리기 전 validationQuery를 실행해서 테스트하라는 것)

- url="jdbc:~~~~~~~~~~~~~~~~~~~~~~~~?autoReconnect=true"


Spring-boot의 경우 application.properties 파일에 다음을 추가하면 된다.

spring.datasource.url=jdbc:~~~~~~~~~~~~~~?autoReconnect=true

spring.datasource.dbcp.test-on-borrow=true

spring.datasource.dbcp.validation-query=select 1



 Other Contents 

댓글을 달아 주세요

티스토리 툴바