IT/JAVA

[Springboot] java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.

월공 2022. 3. 25. 13:58
728x90
300x250

환경 : 로컬, SpringBoot 2.6.1, HikariCP , 5.5.68-MariaDB

 

* HikariCP 가 뭐냐 ?

- SpringBoot 2.0 부터 기본 라이브러리로 탑재되어있는 DataBase Connection Pool (DBCP) 이다.

 

* Connection Pool 이 뭐냐 ?

- DB와 연결을 미리 만들어두고 DB접근시 pool 에 남아있는 커넥션 중 하나를 받아와서 사용한뒤 반환

쉽게 말해서 사용자가 요청할때마다 연결을 만들고 끊고 만들고 끊고 하기엔 상당히 비효율적이니 , 미리 연결을 만들어놓은거 갖다 쓰는거라고 보면된다.

 

WARN com.zaxxer.hikari.pool.PoolBase - HikariPool-2 - Failed to validate connection net.sf.log4jdbc.sql.jdbcapi.ConnectionSpy@42f1dee (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value.
[2022-03-25 10:54:18:55967][HikariPool-2 connection closer] ERROR jdbc.sqltiming - 15. Connection.setNetworkTimeout(com.zaxxer.hikari.pool.PoolBase$SynchronousExecutor@db87dd3, 15000;
java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.

....

생략

 

원인 : 

 

mariaDB 설정에 wait-timeout 라는놈이 있는데 이게 30초로 되어있었기 때문에 DB 연결후 아무 동작없이 30초만 지나면 connection 이 끊겨서 springBoot 측에서 더이상 DB 접근을 못해서 발생한 에러.

Hikari 는 스스로 미사용된 커넥션을 제거하고 새로 생성하는 방식이여서 해당 설정을 변경해줘야함

 

해결방법 : 

 

1. mariaDB 측에서의 wait_timeout 설정을 늘려주는 방법도 있겠지만 별로 선호하고싶진않음.

 

2. 스프링부트 측에 application_properties 설정을 아래처럼 추가해준다.

DbConfig 파일에 따라 중간에 hikari가 붙을수 있고 안붙을수 있는점 참고.

spring.db1.datasource.maxLifetime=30000​

maxLifetime 기본값은 30분 (소스상의 단위는 ms) 이고, 최소 30초 이상 설정해야한다. 30초 미만으로 작성하면 강제로 기본값 30분으로 들어간다고한다.

 

이렇게 해결을 하긴 했는데 여기저기 찾아본 결과 mysql wait_timeout 보다 2~3초 정도 적게 잡는게 좋다고해서

maxLifetime 은 30초로 잡되 wait_timeout 를 기존에 30초보다 2~3초 정도 늘려줄 생각이다.

 

 

그 외 :

 

Hikari 를 제외한 기존 다른 커넥션 풀들은 위와 같은 경우를 방지하고자 validation query  (SELECT 1 )를 주기적으로 날렸다고 함.

 

mysql 에서 wait_timeout 및 기타정보 확인 쿼리문

SHOW GLOBAL variables like '%timeout';
728x90
300x250