반응형

약간 올드한 방식이지만 디비로 분산락을 구현한 사례가 있어서 정리한다.

 

락을 거는 테이블이 있어야 하고, 락을 거는 역할을 하는 서비스가 있어야 한다

  public void runSynchronousTask(TaskKey taskKey, Runnable task) {
    startSynchronousTask(taskKey); //디비에 키 저장

    try {
      task.run(); //비즈니스 로직 실행
    } finally {
      endSynchronousTask(taskKey); //디비에 키 삭제
    }
  }
  
    private void startSynchronousTask(TaskKey taskKey) {
    try {
      insertTaskKey(taskKey);

    } catch (Exception e) {
      if (selectTaskKeyCount(taskKey) > ZERO) {
        throw BadukTaskException.FAIL_START_SYNCHRONOUS_TASK;
      }

      if (updateTaskKey(taskKey) != SUCCESS) {
        throw BadukTaskException.FAIL_START_SYNCHRONOUS_TASK;
      }
    }
  }
  
    private void endSynchronousTask(TaskKey taskKey) {
    try {
      deleteTaskKey(taskKey);
    } catch (Exception e) {
      deleteTaskKey(taskKey);
    }
  }

 

사용처에서 아래와 같이 사용하면 된다. (자바6기준..)

 public ApiResponse giveEventMoney(final EventMoneyApiRequest eventMoneyApiRequest) {
    runSynchronousTask(
       generateLockKey(),  // lock key
        new Runnable() {
          @Override
          public void run() {
            int resultCode = giveMoney();
            if (resultCode != SUCCESS_CODE) {
              throw new ApiException(ApiErrorCode.FAIL_MONEY_PAYMENT);
            }
          }
        });

    return ApiResponse.OK();
  }

1. DB 자체 락 구현

DB를 사용해 특정 키를 기반으로 락을 관리하고 동시 실행을 방지하는 방식.

장점

  1. 데이터와 락 관리의 일원화:
    • 락이 저장되는 위치와 애플리케이션 데이터가 동일한 데이터베이스에 존재하므로 별도의 외부 시스템 없이 처리 가능.
    • DB 트랜잭션과 자연스럽게 통합되어 데이터 일관성을 유지하기 쉬움.
  2. 분산 환경 지원:
    • 여러 인스턴스에서 동일한 DB를 바라보므로 클러스터 환경에서도 동기화를 보장.
  3. 의존성 최소화:
    • 별도의 락 관리 시스템(Redis, ZooKeeper 등)을 도입할 필요 없이 DB만으로 해결 가능.

단점

  1. 성능/확장성 제한:
    • 락 관리(INSERT/DELETE)를 위해 DB I/O가 발생하므로 빈번한 락 작업이 성능에 영향을 줄 수 있음.
    • 대량 트래픽 시 DB 부하를 초래할 가능성.
  2. 잠금 해제 누락 위험:
    • 애플리케이션 장애 또는 네트워크 문제로 인해 finally 블록이 실행되지 않으면 락이 DB에 남아 다른 프로세스가 진행되지 못할 수 있음.
  3. 락의 유효 시간 관리 필요:
    • 만약 비즈니스 로직이 예상보다 오래 걸리거나 문제가 발생해 락이 해제되지 않으면, 추가적인 재처리 로직이 필요함.

2. 디비 네임드 락

장점

  1. 성능:
    • 데이터베이스 내부에서 처리되므로 빠르고 효율적.
  2. 자동 해제:
    • 세션 종료 시 락이 자동으로 해제되므로, 애플리케이션 장애로 락이 남아있는 문제를 방지.
  3. 간단한 사용:
    • 복잡한 로직 없이 락 획득/해제를 호출만으로 구현 가능.
  4. 분산 환경 지원:
    • 동일한 데이터베이스를 사용하는 여러 애플리케이션 인스턴스 간의 락 동기화 가능.

단점

  1. 트랜잭션 제약:
    • 네임드 락은 일반적으로 트랜잭션 경계와는 독립적으로 동작하므로, 데이터와 락의 일관성을 따로 관리해야 함.
  2. 락 관리 제한:
    • 락의 TTL이나 재시도 로직 등을 세밀하게 제어하기 어려움.
  3. 데드락 위험:
    • 잘못된 사용으로 인해 데드락 발생 가능.

추가적인 내용 참고

2024.11.01 - [개발/sql] - [분산] mysql 네임드락

728x90
반응형

+ Recent posts