비관적 락

남기은·2025년 11월 26일

동시성 제어

목록 보기
3/7

비관적 락이란?

낙관적 락과는 반대로 트랜잭션 간의 충돌이 발생할 가능성이 높다고 가정하고
트랜잭션이 데이터를 읽기/수정하기 전에 미리 락을 걸어 다른 트랜잭션의 접근을 락을 통해 제한하는 방식이다.

동작 과정

아래는 두 개의 트랜잭션이 동시에 같은 데이터를 수정하려고 할 때의 흐름이다.

  1. Transaction 1:
    게시글 1번의 좋아요 정보를 SELECT ... FOR UPDATE 로 조회
    → 게시글 1번의 좋아요 정보에 대해 Exclusive Lock(X-Lock) 획득

  2. Transaction 2:
    같은 게시글(1번)에 좋아요 요청을 보내며 SELECT ... FOR UPDATE 실행 시도
    → T1이 X-Lock을 보유 중이므로 즉시 처리되지 않고 락이 해제될 때까지 대기(블로킹)

  3. Transaction 1:
    좋아요 카운트를 +1로 업데이트한 뒤 COMMIT
    → COMMIT과 함께 X-Lock 해제

  4. Transaction 2:
    대기하던 락을 획득하여 게시글 1번의 좋아요 정보를 SELECT ... FOR UPDATE 로 조회
    → 이후 좋아요 카운트를 +1 업데이트 진행

  5. Transaction 2:
    업데이트 후 COMMIT
    → X-Lock 해제

구현방법

1. 좋아요 증가 로직에서 Post에 비관적 락 적용

  • @Lock(LockModeType.PESSIMISTIC_WRITE)를 사용하여 Post의 좋아요 정보를 조회할 때 X-Lock을 획득하도록 설정

2. 좋아요 증가 시 사용되는 조회 메서드 변경

  • 기존 일반 조회 : findById (락 없음)
  • 비관적 락 적용 조회 : findByWithPessimisticLock
    → 좋아요 증가 기능에서만 비관적 락 적용 메서드를 사용하도록 변경

3. 실행결과

  • 100번의 동시 요청을 실행
  • 요청마다 Post의 좋아요 정보에 X-Lock이 걸리기 때문에 순차적으로 처리됨
  • 최종적으로 Post의 like_count가 100이 되는 것을 확인

profile
느리지만 꾸준한 개발자 남기은입니다

0개의 댓글