[Spring/mybatis] HTTP Status 500 - Internal Server Error 발생시 해결
HTTP Status 500 - Internal Server Error
CommunicationsException: the last packet successfully received from the server was 134,135,982 milliseconds ago.
해당 문제는 mysql이 (일반적으로) 8시간 이상 접근이 없으면, 해당 커넥션풀을 끊어버려서 생기는 에러일 확률이 높다.
해결하기 위해선 접근시간을 늘리거나(대부분 추천하지 않는다고 한다.) 오토리커넥트 후 재접속시 1줄 이상의 결과값을 내는 쿼리를 보내는 것이라고 한다.
db.properteis 파일의 url 경로 혹은 데이터소스에 직접 데이터베이스 url을 입력했을 경우 해당 주소 뒤에
?autoReconnect=true
를 붙이고
datasource 프로퍼티에
<property name="driver" 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"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="7200000"/>
validationQuery : 1의 결과가 나오는 한줄의 쿼리를 던진다.
testWhileldle : 커넥션이 놀고 있을 때, validationQuery를 통한 유효성 검사 여부
timeBetweenEvictionRunsMillis : 해당 시간마다 유효성 검사 진행
이 세줄을 추가하라는 글이 대부분이다.
근데 나는 이 세줄을 추가하면 무조건 온갖 매핑 에러가 발생했다. 그래서 해당 클래스파일의 @Autowired 어노테이션을 지워보기도 했는데 그러면 또 다른 오류가 발생하고.. 정작 어노테이션을 지우고 위 세줄을 지우면 매핑이 안되서 오류가 발생... (init 메소드 호출시부터 발생 하는 것은 아니라 일단 실행은 되는데 해당 클래스 파일이 작동하는 페이지에서 에러가 발생한다..)
제일 눈에 띄게 발생했던 오류가 UnsatisfiedDependencyException 인데, 검색해보면 엄한 클래스 파일 건들지 말고 db관련 프로퍼티 파일이나 xml에 문제가 있는 것이니 db주소에 오타있는지 이런 것들을 확인하라는 글 뿐, 정작 validationQuery와의 관계에 대한 글은 한국어웹이든 영어웹이든 찾을 수가 없었다. 분명 저 세줄을 추가 해서 생긴게 분명한데 왜 validationQuery와 UnsatisfiedDependencyException를 같이 검색해도 해당하는 내용이 나오지 않는 걸까?
해결하고 난 지금도 이 부분은 정말 의문점이다. 분명 나랑 같은 방식으로 해결한 사람이 있을텐데 관련 글은 찾아볼 수가 없었다. UnsatisfiedDependencyException이 발생하는 경우가 다른 경우에도 많아서 해당 자료들이 묻힌건지..
그럼 이게 왜 발생하느냐..? 이건, dataSource의 타입을 봐야 알 수 있는 건데, 무작정 뭐든간에 데이터소스에 저 세줄을 추가하라고 하니 문제가 발생할 수 밖에 없는 거 였다.
위의 내용은 DBCP타입의 dataSource일 경우 (<dataSource type="DBCP">) 올바른 해결법이 맞다. 그리고 더 먼저부터 있던 거고 이 내용으로 해결방법에 대한 글이 많은 것은 당연한 것 이긴 하다.
근데 만약 내 dataSource의 타입이 POOLED라면?(<dataSource type="POOLED">) 위의 해결책은 적절하지 않고 맞지 않는 내용의 프로퍼티가 있으니 당연히 매핑이 실패할 수 밖에 없는 것 이었다.
스프링책에 있는 20page 남짓한 mybatis 사용법만 보고 사용하고 있으니 바른 해결책이 나올리가 없는 것이기도 하고.. 해당 내용은 ibatis에서 사용되던 validationQuery가 mybatis로 넘어오면서 사라졌기 때문이다. 뭐 java 배울 때도 구버전에선 쓰이던 메소드가 안정성이나 여러가지 이유로 사용을 권장하지 않거나 사용되지 않는 경우가 많았으니 이를 당연히 생각해야하는 건가 싶다가도 이게 메소드가 사라진건지 아니면 다른 설정이 잘못된건지 내가 어떻게 알겠는가.. 배우고 있는 입장인데 ㅠㅠ
여튼 결론을 말하자면 같은 역할을 하는 프로퍼티가 POOLED타입의 dataSource에도 있다는 것.
dataSource의 프로퍼티 밑에 validationQuery와 친구들 대신 아래의 세줄을 입력해주면 되는 것이었다.
<property name="poolPingEnabled" value="true" /><property name="poolPingQuery" value="select 1" />
<property name="poolPingConnectionsNotUsedFor" value="6000000" />
poolPingEnabled : poolpingquery를 사용해 유효성 검사를 할것인지 여부
poolPingQuery : 1의 결과가 나오는 한줄의 쿼리를 던진다.
poolPingConnectionsNotUsedFor : 해당 시간마다 유효성 검사를 진행
여기에 써놓은 역할을 보고.. 다시 위로 올라가 validationQuery쪽 역할을 보면 이름은 다르지만 하는 일은 완전히 똑같다는 것을 알 수 있다. 이 세줄을 추가한 결과 내 웹프로그램은 아주 팽팽 잘 돌아간다.. 이제 서버에 올려놓은 것이 8시간 후에도 500에러 없이 돌아가는지만 확인 하면 될 것 같다.