Connection Pool과 @Transactional: 효율적인 데이터베이스 관리를 위한 핵심 개념
데이터베이스와 상호작용하는 애플리케이션을 개발할 때, 성능과 안정성을 확보하기 위해 Connection Pool과 @Transactional을 이해하고 활용하는 것이 필수적입니다. 이번 글에서는 두 개념이 어떻게 동작하는지, 그리고 실제 개발에서 어떻게 활용하면 좋은지에 대해 알아보겠습니다.
1. Connection Pool이란?
데이터베이스에 연결하는 과정은 생각보다 비용이 많이 듭니다. 새로운 연결을 생성하는 과정에서 네트워크 통신이 발생하고, 인증 및 세션 설정도 필요하기 때문이죠. 이를 해결하기 위해 Connection Pool을 사용합니다.
✅ Connection Pool의 동작 방식
- 초기화: 애플리케이션이 시작될 때, 설정된 개수만큼 데이터베이스 연결을 생성하여 풀(Pool)에 저장합니다.
- 요청 처리: 클라이언트의 요청이 들어오면, 풀에서 사용 가능한 연결을 할당합니다.
- 반환: 작업이 끝나면 해당 연결을 다시 풀에 반환하여 재사용할 수 있도록 합니다.
즉, 매번 새로운 연결을 만들지 않고, 기존 연결을 재사용함으로써 성능을 최적화하는 것이 핵심입니다.
2. Spring Boot의 커넥션 풀 관리 방식
Spring Boot는 기본적으로 HikariCP를 사용하여 커넥션 풀을 관리합니다. HikariCP는 성능이 뛰어나고 가볍기 때문에 널리 사용됩니다.
🔹 Spring Boot의 기본 Connection Pool 설정
Spring Boot 2.x 이상에서는 별도의 설정 없이도 기본적으로 HikariCP가 활성화됩니다. 즉, application.yml
을 작성하지 않아도 Spring Boot가 적절한 기본값을 사용하여 커넥션 풀을 자동으로 관리합니다.
기본값:
- 최소 유휴 커넥션: 10
- 최대 커넥션 풀 크기: 10
- 커넥션 타임아웃: 30초
- 최대 생명주기: 30분
🔹 커넥션 풀 커스텀 설정하기
기본값을 변경하고 싶다면 application.yml
또는 application.properties
에서 설정할 수 있습니다.
application.yml
예제:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5 # 최소 유휴 커넥션 개수
maximum-pool-size: 20 # 최대 커넥션 개수
idle-timeout: 30000 # 유휴 상태 연결 유지 시간 (ms)
max-lifetime: 1800000 # 커넥션 최대 생명 주기 (ms)
connection-timeout: 30000 # 커넥션 요청 대기 시간 (ms)
✅ Spring Boot의 Connection Pool 특징
- 기본적으로 HikariCP 사용: 별도의 설정이 없으면 Spring Boot는 HikariCP를 자동으로 활성화합니다.
- 자동 설정:
spring.datasource.*
설정만 추가하면 별도의 설정 없이 Connection Pool을 사용할 수 있습니다. - 최적화된 커넥션 관리: 빠른 성능과 낮은 메모리 사용량을 제공하며, 커넥션이 유휴 상태가 될 경우 자동으로 정리됩니다.
3. @Transactional이란?
스프링에서는 데이터베이스 트랜잭션을 관리하기 위해 @Transactional
어노테이션을 제공합니다. 이를 사용하면 서비스 레이어에서 트랜잭션을 간단하게 적용할 수 있습니다.
@Service
public class UserService {
@Transactional
public void updateUser(Long userId, String name) {
User user = userRepository.findById(userId).orElseThrow();
user.setName(name);
}
}
이렇게 @Transactional
을 사용하면, 해당 메서드가 실행될 때 트랜잭션이 시작되고, 정상적으로 끝나면 커밋(commit), 오류가 발생하면 자동으로 롤백(rollback) 됩니다.
🔹 주요 속성
propagation
: 트랜잭션 전파 방식을 정의합니다. 기존 트랜잭션이 존재할 때 새로운 트랜잭션을 만들지 여부 등을 설정할 수 있습니다.isolation
: 동시에 실행되는 트랜잭션 간의 격리 수준을 설정합니다.timeout
: 트랜잭션이 수행될 최대 시간을 설정합니다.readOnly
: 읽기 전용 여부를 설정하여 불필요한 변경을 방지합니다.
4. @Transactional(readOnly = true)
란?
조회(SELECT)만 수행하는 경우에는 @Transactional(readOnly = true)
를 설정하는 것이 좋습니다. 이를 적용하면 불필요한 트랜잭션 오버헤드를 줄일 수 있습니다.
@Transactional(readOnly = true)
public User findUser(Long userId) {
return userRepository.findById(userId).orElseThrow();
}
5. Connection Pool과 @Transactional의 관계
Connection Pool과 @Transactional은 함께 사용될 때 더욱 강력한 효과를 발휘합니다.
- Connection Pool을 활용하면 데이터베이스 연결을 재사용하여 성능을 높일 수 있습니다.
@Transactional
을 통해 트랜잭션을 효과적으로 관리할 수 있습니다.- 트랜잭션 범위 내에서 Connection Pool의 연결을 효율적으로 사용하고, 작업이 끝나면 자동으로 반환됩니다.
이러한 조합을 잘 활용하면 데이터베이스 성능을 극대화할 수 있습니다.
6. 결론
Connection Pool과 @Transactional
은 데이터베이스 성능과 안정성을 확보하는 데 핵심적인 역할을 합니다.
- Spring Boot는 HikariCP를 기본적으로 활성화하며,
application.yml
없이도 기본값으로 운영됩니다. - 필요에 따라 Connection Pool 설정을 커스텀할 수 있습니다.
@Transactional
을 활용하면 일관된 트랜잭션 처리가 가능합니다.- 조회 작업에는
@Transactional(readOnly = true)
를 적용하여 최적의 성능을 유지해야 합니다.
Reference
'IT 기술 > Spring boot' 카테고리의 다른 글
Controller에서 Request Body를 읽지 못하는 문제 해결 - Interceptor를 통한 RequestBody 로그 시도인 경우 (0) | 2025.04.06 |
---|---|
Spring vs Spring Boot: 차이점과 선택 기준 (1) | 2025.03.18 |
Spring Boot에서 Security 적용 시 H2 Console(/h2-console) 접근 불가 문제 해결 방법 (0) | 2025.03.05 |
/gradlew bootRun은 어떻게 동작하는가? (1) | 2025.02.22 |