[MariaDB] 동시성 문제 실무 해결책

이지연·2025년 11월 25일

개요

데이터베이스에서 발생하는 동시성 문제(lost update)를 해결하는 네 가지 대표적인 방법인 낙관적 락비관적 락, 프로그램 차원에서의 락, Redis 사용에 대해서 간략하게 정리해보겠음


낙관적 락 (Optimistic Lock)

  • 트랜잭션들이 동시에 같은 데이터를 수정하는 일이 자주 발생하지 않는다는 가정 하에,

  • 데이터 수정 시점에 버전 정보(version field)를 기준으로 충돌을 감지하고 예외 처리를 한다.

  • 예를 들어, 두 트랜잭션 A, B가 version=1을 읽은 상태에서 동시에 수정 시도할 때:

    1. A가 먼저 해당 행을 version=1 → version=2 로 업데이트에 성공
    2. B가 version=1로부터 업데이트를 시도하지만, 이미 버전이 바뀌어 실패(에러 발생)
    3. B는 충돌을 감지하고 작업을 다시 시도하거나 에러 처리
  • 낙관적 락은 DB 락을 사용하지 않고, 버전 필드를 통해 충돌을 감지하는 방식이기에 동시성 성능에는 유리하다.

  • JPA 등의 ORM 도구에서는 보통 @Version 어노테이션을 사용해 손쉽게 구현 가능하다.

-- 예시: UPDATE 시 버전 검사하는 쿼리
UPDATE account
SET balance = balance - 100, version = version + 1
WHERE user_id = 1 AND version = 1;

비관적 락 (Pessimistic Lock, 배타락)

  • 데이터 충돌 가능성이 높다고 판단할 때 미리 트랜잭션 단위로 락을 걸어 다른 접근을 차단한다.
  • SELECT ... FOR UPDATE 구문등으로 특정 행에 배타적 락을 건다. - 배타락과 공유락이 있다.

-- 배타락 예시
SELECT post_count INTO cnt
FROM author
WHERE id = 2 FOR UPDATE;

프로그램 차원에서 Lock

  • 프로그램(Java)에서 멀티스레드 환경에서 동시에 하나의 스레드만 특정 코드 영역(임계 영역)에 접근할 수 있도록 보장
  • 프로그램 레벨에서는 synchronized 같은 동기화 기법과 유사한 원리다.
  • 다만, 락이 걸려 있는 시간이 길어지면다른 트랜잭션은 락이 풀릴 때까지 대기해야 하므로 전체 시스템의 처리량(동시성)이 떨어질 수 있고, 순차적 쿼리 실행이 보장 되지 않아 완전한 해결책은 아니다.
  • 다만 db차원의 lock 아니므로 DB에는 동시에 update작업을 시도할 여지가 있어, 여전히 동시성 문제 발생할 수 있는 여지가 있음.


Redis 활용

  • Redis는 싱글 스레드 기반의 인메모리 데이터 저장소로,
  • 내부 동시성 처리가 단일 스레드로 일어나 락 경쟁이 적다.
  • RDB(MySQL)와 병행 운영하여 빠른 데이터 접근 및 동시성 처리를 보완하는 용도로 많이 사용한다.
  • 복잡한 분산 락이나 캐시 일관성 문제도 Redis의 네임드락 기능 등으로 일부 해결 가능하다.
  • 재고관리를 redis에서 하고 추후 rdb에 update하는 방식 활용가능.


마치며

동시성문제를 해결하는 프로젝트를 진행해볼 수 있으면 좋은 양분이 될거같다.

profile
Eazy하게

1개의 댓글

comment-user-thumbnail
2025년 12월 11일

낙관적 락과 비관적 락?
이건 뭐 거의 비틀즈 수준이죠 이건 뭐…
정말 낭만있네요 낭만개발자 이지연으로 이름바꾸세요

답글 달기