테스트 클래스를 일정 수 이상 묶어서 실행하면, 어느 정도 실행하다가 갑자기 JDBC Connection을 무한히 대기하는 현상
```
oracle.net.ns.NetException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found.
```
```sql
select * from v$resource_limit where resource_name = 'processes';
```
- 프로세스 수가 최대치에 육박하여 더 이상 요청을 처리할 수 없어 발생하는 문제. 커넥션 풀 close를 제대로 하지 않는 것으로 보임.
- HikariDataSource(==ConnectionPool)의 maximumPoolSize 기본값은 10인데, 이를 3으로 변경하고 수행하니 커넥션에 여유가 생겨 pending 걸리던 구간 통과하여 끝까지 TC 수행됨.
- 하지만 이는 임시방편이고 테스트 후 connection close를 자동으로 수행할 방법 필요함.
확인 결과, 아래와 같은 상황임.
- 테스트 클래스 마다 [DB는 초기화 하지 않고, Docker 컨테이너도 초기화 하지 않고, `` TestDatabaseConfig``만 초기화 함]
- `` TestDatabaseConfig``가 매 테스트 클래스 마다 호출되면서 별도의 `` HikariPool``을 생성함
- 테스트가 종료되어도 이 `` HikariPool``이 가지고 있는 connection이 close 되지 않아서, 오라클에서 처리할 수 있는 최대 커넥션 수에 육박하면 pending
- 모든 테스트가 종료된 후 마지막에 모든 `` HikariPool``을 몰아서 닫고 있다.
- 각 테스트 마다 `` HikariDataSource``를 수동으로 DI 받아 cleanup에서 close() 호출하면 제대로 동작한다
```
2021-10-19 13:59:21.467 [Thread-12] INFO com.zaxxer.hikari.HikariDataSource - HIKARI_POOL2021-10-19T13:58:32.584 - Shutdown initiated...
2021-10-19 13:59:21.467 [Thread-12] DEBUG com.zaxxer.hikari.pool.HikariPool - HIKARI_POOL2021-10-19T13:58:32.584 - Before shutdown stats (total=3, active=0, idle=3, waiting=0)
2021-10-19 13:59:21.473 [Thread-25] INFO com.zaxxer.hikari.HikariDataSource - HIKARI_POOL2021-10-19T13:58:40.102 - Shutdown initiated...
2021-10-19 13:59:21.473 [Thread-25] DEBUG com.zaxxer.hikari.pool.HikariPool - HIKARI_POOL2021-10-19T13:58:40.102 - Before shutdown stats (total=3, active=0, idle=3, waiting=0)
```
이는 Spring TestContext Framework 가 "같은 설정에 대해서만" `` ApplicationContext``를 재사용 하기 때문임.
해결 방안 선택지
- 굳이 TestDatabaseConfig를 매 테스트 마다 호출할 필요가 없으니, 전 테스트에 걸쳐 딱 한 번만 호출하도록 수정
- 모든 TestClass가 같은 `` ApplicationContext``를 사용하도록 구성. 가능한가?
- context 캐시를 활용할 수 있으므로 속도 이점이 있어서 제일 괜찮아 보이는 방법
- 하지만 테스트 마다 basePackage나 Bean 등을 별도로 지정하여 실행하는 경우라면? 모든 패키지에 대한 통합 context를 생성하지 않는 한, 잡 별로(TC별로) `` ApplicationContext``가 다를 수 밖에 없다.
테스트 클래스 하나 끝나면, 자동으로 HikariPool 삭제 하도록 추가 설정- 하지만 이 경우, ApplicationContext 캐시를 재사용 할 때 HikariPool이 이미 닫혀있어 에러 발생할 듯
- 모든 통합 테스트에 `` @DiretiesContext``를 붙여 클래스가 끝날 때 `` ApplicationContext``를 삭제하도록 변경
- 2번과 비슷하지만 ApplicationContext 자체를 초기화 하는 것이라 잘 동작함.
- 초기화 시점을 `` AFTER_CLASS``로 두면 된다.
- 기본 context cache maximum size가 32이므로 이에 맞게 HikariPool size 또는 오라클 프로세스 수용치를 조정
- HikariPool Connection size를 3으로 조절하면, 32*3 = 96 이므로 기본 오라클 프로세스 max인 100 이하라서 수용 가능함.
- 또는 context cache maximum size를 줄이거나, 오라클 프로세스 max를 늘리는 방법도 가능.
1,2번은 사용할 수 없는 선택지이고
모든 TC에 DirtiesContext를 붙이는 것(3) 보다, context cache는 캐시대로 사용할 수 있도록 4번 방안으로 해결하는 것이 무난해 보임.
'Java Stack > Spring' 카테고리의 다른 글
spring-webmvc 에서 SpringBoot로 단계별로 전환하기 (0) | 2023.04.01 |
---|---|
[Spring] EventListener (0) | 2022.04.17 |
[Spring] DB 관련 : Mybatis CustomTypeHandler (0) | 2021.03.31 |
[Spring] WebClient (0) | 2021.03.14 |
spring-webmvc 5.2.4 이하(springboot 2.2.5 이하) 버전에서 발생하는 응답지연 현상 (0) | 2021.01.14 |