일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 명령어공부
- SQLRecoverableException
- plsql
- 나선형 모형
- 클린코드
- pl/sql
- table scan
- avax.net.ssl.SSLHandshakeException:
- springboot
- 프로토타입 모형
- mysql 튜닝
- OpenAPI
- 인증서만료에러
- 스크럼기법
- Law of Demeter
- was버그
- was SQLRecoverableException
- vue
- CSS
- 커맨드공부
- Bandit Level 6 → Level 7
- 폭포수 모형
- 에자일 모형
- Bandit Level 5
- 디미터 법칙
- 시스템 파악
- 변수명 짓는법
- 시스템 파악 정리
- Bandit Level 6
- java.sql.SQLRecoverableException
- Today
- Total
개발햄비
[버그해결]MySQL , Maria DB Connection을 잃어버리는 문제 해결 본문
결합 테스트를 후 모든 게 정상이었던 시스템에 갑자기 Exception에러가 발생하였다.
org.springframework.dao.DataAccessResourceFailureException: could not execute query; nested exception is org.hibernate.exception.JDBCConnectionException: could not execute query
The last packet successfully received from the server was 35,986,917 milliseconds ago. The last packet sent successfully to the server was 22 milliseconds ago. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
*현장 보안 때문에 에러코드는 다른 홈페이지에서 카피해옴
위와 같이 JDBCConnectionException, CommunicationsException 에러가 발생하였다
이유를 찾아보니 Mysql 의 경우 기본적으로 8시간 안에 request가 오지 않으면 강제적으로 Connection을 닫아버리기 때문에
오래 방치해두고 request를 날리면 먹통이 되는 에러였다.
해결방법은 아래와 같다
DB접속 URL에
url="jdbc:mysql://localhost:3306/test?autoReconnect=true" 또는 validationQuery="select 1"
을 설정해주면 된다.
하지만 autoReconnect 옵션은 쿼리를 수행한 다음 DB 세션에 문제가 있으면 단순히 SQLException 리턴 후 재접속 처리를 한다.
하지만 문제는 트랜잭션 구동 환경에서 수행 중이던 트랜잭션은 롤백이 되어야 하고, 남은 트랜잭션은 수행이 되지 않아야 되는데, autoReconnect 옵션은 이런 처리를 해주지 않기 때문이다.
문제를 막기 위해서 autoReconnect=true인 환경에서는 SQLException이 발생하는 경우에, 해당 트랜잭션이 더 이상 진행되지 않도록 App 단에서 직접 예외 처리를 해줘야 하고, MySQL 레퍼런스 매뉴얼에서도 autoRecoonect 옵션 사용은 권장하지 않고 있다.
Property Name |
Definition |
Default Value |
Since Version |
autoReconnect |
Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly. Alternatively, investigate setting the MySQL server variable "wait_timeout" to some high value rather than the default of 8 hours. |
false |
1.1 |
트랜잭션을 사용하는 환경이라면 DB 세션의 재접속 처리는 JDBC의 autoReconnect 설정이 아닌
DBCP의 validationQuery="select 1" 기능을 사용하는 것이 적합하다.
java에서 DB를 사용하기 전에 해당 connection 이 정상적인지 검사를 하도록 하는 것이다. 이 옵션이 validationQuery 파라미터이다.
- MySQL
- validationQuery="select 1"
- 오라클의 경우
- validationQuery="select 1 from dual"
'개발 > 버그 해결 기록' 카테고리의 다른 글
[버그해결] DB접속 오류 java.sql.SQLRecoverableException: IO Error: Connection (0) | 2021.10.02 |
---|---|
[버그해결] java.security.cert.CertPathValidatorException: validity check failed (0) | 2021.05.23 |
Cannot find module 'semver' 해결 (0) | 2019.10.09 |
[에러해결] watson Assistant API 요청시 apikey header로 날리기 (0) | 2019.04.24 |
[heroku] App not compatible with buildpack 에러 해결 (3) | 2019.04.06 |