동시성이란 여러 작업이 동일한 자원에 동시에 접근하거나 실행될 때 실행 순서나 시점에 따라 결과가 달라질 수 있는 상태를 말한다. 특히 웹 애플리케이션에서는 여러 사용자의 요청이 병렬로 들어오게 되며 이 과정에서 동일한 데이터에 대한 수정이나 조회가 중복될 가능성이 높다. 이때 적절한 제어가 이루어지지 않으면 데이터 정합성이 쉽게 무너질 수 있다.
예시: 사용자가 동시에 같은 좌석을 예약하거나 동일한 포인트를 두 번 사용하는 경우
락(Lock)은 이러한 동시성 문제를 해결하기 위해 데이터에 대한 접근을 제한하는 제어 장치입니다. 한 번에 하나의 트랜잭션만 해당 자원을 접근하도록 제한함으로써 정합성을 보장합니다.
🔒 락 전략 비교: 언제, 왜 사용하는가?
항목 | 낙관적 락 (Optimistic Lock) | 비관적 락 (Pessimistic Lock) |
---|---|---|
기본 전제 | 대부분의 요청은 충돌하지 않음 | 충돌 가능성이 높다고 가정 |
처리 방식 | 먼저 업데이트 시도 → 버전 불일치 시 예외 발생 | 먼저 락 획득 → 다른 트랜잭션은 대기 또는 차단 |
충돌 시 처리 | 예외 발생 → 실패로 처리하거나 재시도 | 충돌 자체 발생하지 않음 (락 해제까지 대기) |
적합한 상황 | 일부만 성공해도 되고 실패를 허용할 수 있는 경우 → "하나만 성공해도 충분한" 케이스 | 반드시 모든 요청이 순차적으로 처리되어야 하는 경우 → "실패 없이 모두 성공시켜야 하는" 케이스 |
장점 | 락이 없어 성능 유리 병렬 처리 효율적 | 정합성 보장 강력 처리 순서 보장 |
단점 | 충돌 시 실패 발생 예외 처리 필요 | 락 경합 시 성능 저하, 데드락 위험 |
콘서트 예약 예시 | 동일 좌석을 500명이 동시에 예약 → 1명만 성공, 나머지는 "이미 예약됨"으로 실패 ✅ 낙관적 락 적합 | 모두 순차적으로 예약을 진행해야 함 → 대기 시간 허용 가능, 실패 없이 처리 필요 ✅ 비관적 락 적합 |
Spring JPA 적용 방법 | @Version 필드 + 예외 처리ObjectOptimisticLockingFailureException |
@Lock(LockModeType.PESSIMISTIC_WRITE) + 트랜잭션 제어 |
포인트 충전 예시 - 시퀀스 다이어그램