자바 소켓 프로그램 + 스케줄러로 구성된 프로세스를 실서버 운용중에 있었는데, 주말간 문제가 없었는지 확인해보니 주말사이에 스케줄러가 동작할때마다 에러를 뿜어내고 있었습니다.
[2020-07-18 11:00:00] ERROR (utils.SqlSessionUtils - selectList:92) - Exception
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit. Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 86,387,538 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago.
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at kr.or.kisa.ktoaInterlock.utils.SqlSessionUtils.selectList(SqlSessionUtils.java:90)
at kr.or.kisa.ktoaInterlock.dao.InterlockDao.selectYesterdayReportList(InterlockDao.java:95)
at kr.or.kisa.ktoaInterlock.scheduler.InterLockScheduler.execute(InterLockScheduler.java:40)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
와 같은 에러를 출력중이였는데...
DB는 mysql을 사용중이며 해당 스케줄러는 하루에 한번 돌도록 구성되어 있습니다.
에러 내용을 가지고 검색을 해보니, 너무 오랫동안 mysql을 사용하지 않고 있다가 갑자기 사용하려고 하면 발생하는 에러로 mysql에서 오랫동안 사용을 하지 않으니 강제로 종료해버리는 이슈라고 합니다.
POOLED타입의 옵션을 수정할 필요가 있었고, 옵션들을 살펴봤습니다.
https://mybatis.org/mybatis-3/ko/configuration.html
공식문서를 참고하였고, 다른 포스팅 글들과 함께 참고하여 아래의 3옵션을 확인하였습니다.
poolPingQuery - 커넥션이 작업하기 좋은상태인지 요청을 받을 준비가 되었는지 등 체크하기 위해 DB에 핑쿼리를 날리는 문구를 지정합니다.
poolPingEnabled - 핑쿼리를 사용할지 안할지 설정합니다. default - false
poolPingConnectionsNotUsedFor - 핑쿼리를 얼마나 자주 사용할지 지정합니다. 핑쿼리를 사용할 경우에만 해당 옵션이 동작합니다.(ms)
mybatis 설정쪽에 의미없는 쿼리로 핑을 날리듯이 처리를 할 수 있다고하여 옵션을 추가하였고, 지켜보기로 하였습니다.
문제가 해결된다면 해당 포스팅은 여기서 종료하겠습니다.
설정 수정 옵션
<property name="poolPingQuery" value="select 1"/> <!-- 핑쿼리 추가 -->
<property name="poolPingEnabled" value="true"/> <!-- 핑쿼리 추가 -->
<property name="poolPingConnectionsNotUsedFor" value="7200000"/> <!-- 2시간마다 -->
위 내용처럼 ping처리를 할 수 있는 의미없는 쿼리와 사용하겠다는 옵션을 추가하였습니다.
모든 옵션
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="poolPingQuery" value="select 1"/> <!-- 핑쿼리 추가 -->
<property name="poolPingEnabled" value="true"/> <!-- 핑쿼리 추가 -->
<property name="poolPingConnectionsNotUsedFor" value="7200000"/> <!-- 핑쿼리 추가 -->
<property name="poolMaximumActiveConnections" value="100"/> <!-- 주어진 시간에 존재할수 있는 활성화된 커넥션 수 -->
<property name="poolMaximumIdleConnections" value="100"/> <!-- 주어진 시간에 존재할 수 있는 유휴 커넥션의 수 -->
<property name="poolTimeToWait" value="20000"/> <!-- 풀이 로그 상태를 출력하고 비정상적으로 긴경우 커넥션을 다시얻을려고 시도하는 로우 레벨 셋팅 -->
</dataSource>
</environment>
</environments>