1. 트랜잭션이란?
트랜잭션은 데이터베이스 작업의 최소 단위입니다.
- 여러 작업(쿼리)을 하나로 묶어 모두 성공(commit) 하거나 모두 실패(rollback) 시키는 역할을 합니다.
- 예: 주문 서비스
- 재고 차감 성공 + 주문 생성 성공 → commit
- 재고 차감 성공 + 주문 생성 실패 → rollback (재고 차감도 되돌아감)
즉, 업무의 일관성을 보장하기 위한 핵심 개념입니다.
2. 트랜잭션 범위 지정 (@Transactional)
Spring에서는 @Transactional 애노테이션으로 트랜잭션의 범위를 지정할 수 있습니다.
@Service
public class OrderService {
@Transactional
public void order(Long itemId, Long userId) {
// 1. 재고 차감
itemRepository.decreaseStock(itemId);
// 2. 주문 생성
orderRepository.save(new Order(userId, itemId));
}
}
특징
- order() 메서드 전체가 하나의 트랜잭션으로 묶임
- 둘 중 하나라도 실패 → 전체 롤백
- 모든 과정이 성공해야만 commit
이 방식으로 “재고 차감과 주문 생성은 항상 함께 성공/실패해야 한다”는 업무 규칙을 보장할 수 있습니다.
3. 낙관적 락 vs 비관적 락
트랜잭션과 밀접하게 연관된 개념이 락(lock) 입니다.
- 비관적 락
- 트랜잭션이 시작되자마자 DB row에 락을 걸어 다른 트랜잭션이 접근하지 못하게 함
- 장점: 충돌을 확실히 방지
- 단점: 동시성 높은 환경(예: 티켓팅)에서는 대기 시간이 길어져 성능 저하
- 낙관적 락
- 락을 걸지 않고, 트랜잭션 종료 시점에 버전(Version) 값을 비교해 충돌 감지
- 장점: 락 오버헤드 없음, 트래픽이 적을 때 효율적
- 단점: 충돌 시 롤백 → 재시도 필요
정리: 트래픽이 적은 환경에서는 낙관적 락이, 티켓팅 같은 고트래픽 환경에서는 비관적 락이나 큐/분산락 같은 다른 설계가 필요합니다.
4. 트랜잭션 전파 옵션 (Propagation)
업무 시나리오에 따라 트랜잭션을 같이 묶을지, 따로 처리할지를 지정할 수 있습니다.
- REQUIRED (기본값)
- 기존 트랜잭션이 있으면 합류, 없으면 새로 생성
- 주문 서비스 기본 시나리오
- REQUIRES_NEW
- 무조건 새로운 트랜잭션 시작
- 예: 주문 실패해도 포인트 차감은 반드시 반영해야 하는 경우
- MANDATORY
- 무조건 기존 트랜잭션 안에서 실행, 없으면 예외 발생
- SUPPORTS
- 트랜잭션 있으면 합류, 없어도 그냥 실행 (읽기 전용 작업에 적합)
- NOT_SUPPORTED / NEVER
- 트랜잭션 없이 실행 (로그 기록, 알림 발송 등)
업무 규칙에 따라 트랜잭션 경계를 조절하는 게 핵심입니다.
5. 업무 시나리오 예시
- 주문 처리
- @Transactional(REQUIRED) → 재고 차감 + 주문 생성은 항상 함께 처리
- 포인트 적립
- @Transactional(REQUIRES_NEW) → 주문 실패해도 포인트 적립은 보장
- 알림 발송
- @Transactional(NOT_SUPPORTED) → 알림은 실패해도 본 주문 로직에는 영향 없음
6. 정리
- 트랜잭션은 업무 단위의 원자성을 보장하는 장치
- @Transactional로 범위를 지정해 함께 성공/실패할 작업을 명확히 표현
- 전파 옵션을 통해 업무 규칙에 맞는 트랜잭션 경계를 설정
- 락 전략(낙관적/비관적)은 트래픽 상황과 업무 특성에 맞게 선택
'프로젝트' 카테고리의 다른 글
| 서비스 모니터링의 다음 단계 (0) | 2025.11.06 |
|---|---|
| Prometheus와 Grafana 이해하기 (0) | 2025.11.06 |
| 데이터 페이징(Pagination) 기법 (0) | 2025.09.19 |
| 테스트 커버리지 점진적으로 높이기 (1) | 2025.08.25 |
| JaCoCo + Codecov로 CI 테스트 커버리지 관리하기 (4) | 2025.08.25 |