본문 바로가기
IT/Java

IBATIS MaximumIdleConnections / Connection pooling logic (SimpleDataSource)

by yjacket 2011. 9. 7.
MaximumIdleConnections 
IBATIS 에서는 MaximumActiveConnections 설정으로 connection pool 의 최대 크기를 설정한다.
그런데 이 설정에 대비되는 설정인 MaximumIdleConnections 을 얼핏(본인이 그랬음-_-;)
connection pool 의 최소 크기 설정이라 생각하기 쉬운데 사실은 그렇지 않다.

Ibatis 는 처음부터 최소치만큼 커넥션을 생성해두지 않고 필요시마다 증가시키므로 (이름부터 Max인) MaximumIdleConnections 은 최소값이 아니고, 단지 ArrayList인 idleConnections 의 최대 길이일 뿐이다.

Connection pooling logic
SimpleDataSource 는 내부적으로 connection pool 을 관리하기 위해 
ArrayList 타입 멤버인 idleConnections 와 activeConnections 에 커넥션을 저장한다.

그리고 처음엔 커넥션을 하나도 안만들고 있다가, 요청이 들어올때 다음 순서로 동작한다.

1. idleConnections 에 대기중인 커넥션이 있으면 이를 반환
2. idleConnections 가 없으면 MaximumActiveConnections 초과하지 않을 경우, 새 커넥션을 만들어 반환
3. MaximumActiveConnections을 초과하면, activeConnections 에서 가장 오래된 커넥션을 가져와 체크아웃타임이 MaximumCheckoutTime을 초과할 경우 이 커넥션을 롤백하고 반환
4. MaximumCheckoutTime을 초과하지 않으면 TimeToWait 만큼 기다렸다가 다시 커넥션 획득 시도


자, 이제 본론이다. 다시 MaximumIdleConnections 의 의미를 돌이켜보자.

MaximumIdleConnections 은 최대 유휴 연결(보관) 수,
즉, idle 상태 연결을 최대 얼마나 보관할지 결정하는 설정인데,
주의해야 할 점은 이 설정을 잘못하면 성능에 심각한 문제가 발생 할 수 있다는 것이다.

다음 상황을 가정해보자

MaximumActiveConnections = 50
MaximumIdleConnections = 0

connection pool size 는 최대 50까지 증가하므로 activeConnections.size() 는 50 이하다. 그런데, activeConnections 에 있던 연결이 다 사용되고 나서 pushConnection() 으로 반환될때 해당 연결은 유휴 상태이므로 idleConnections 로 들어가야하지만, idleConnections 는 위 설정에 의해 길이가 0 이상 될 수 없다. 따라서 유휴 상태로 접어드는 연결은 무조건 소멸되며, idleConnections 에 어떤 연결도 없으므로, ibatis 는 매번 새로운 연결을 만들어내게 되므로 connection pool 을 사용하는 의미가 없게 된다.

이러한 성능 저하는 MaximumActiveConnections, MaximumIdleConnections의 차가 크면 클수록 더 심각하게 되므로, 어플리케이션의 성격에 따라 적절하게 설정 되어야 한다.



참조 : com.ibatis.common.jdbc.SimpleDataSource.popConnection(), pushConnection()