Skip to content

Latest commit

 

History

History
72 lines (41 loc) · 2.76 KB

File metadata and controls

72 lines (41 loc) · 2.76 KB

정리

오프라인 선점 잠금 방식은 누군가 수정 화면을 보고 있을 때 수정 화면 자체를 실행하지 못하게 막는다.

엄격하게 데이터 충돌을 막기 위해 누군가 수정 화면을 보고 있을 때 수정 화면 자체를 실행하지 못하게 하는 것이 오프라인 선점 잠금 방식이다.

한 트랜잭션 범위에서만 적용되는 선점 잠금 방식이나 나중에 버전 충돌을 확인하는 비선점 잠금 방식으로는 구현할 수 없다.

img

만약 이런 상황에서 사용자 A가 수정 요청을 수행하지 않는다면 잠금이 해제되지 않으므로 잠금 유효 시간을 가져야 한다.

잠금 유효 시간이 지나면 잠금을 해제해 다른 사용자가 잠금을 다시 구할 수 있도록 해야 한다.

하지만 유효 시간이 지난 뒤 얼마 되지 않아 수정 요청을 수행한다면 실패하게 된다.

이를 방지하기 위해 일정 주기로 유효 시간을 증가시키는 방식이 필요하다.

오프라인 선점 잠금을 위한 LockManager 인터페이스와 관련 클래스

  • 잠금 선점 시도
  • 잠금 확인
  • 잠금 해제
  • 잠금 유효시간 연장
public interface LockManager {
  LockId tryLock(String type, String id) throws LockException;  // 잠금 선점 시도
  void checkLock(LockId lockId) throws LockException;   // 잠금 확인
  void releaseLock(LockId lockId) throws LockException;   // 잠금 해제
  void extendLockExpiration(LockId lockId, long inc) throws LockException;  // 락 유효 시간 연장
}

잠금을 선점한 이후에 실행하는 기능은 다음과 같은 상황을 고려해 잠금이 유효한지 확인해야 한다.

  • 잠금의 유효 시간이 지났으면 이마 다른 사용자가 잠금을 선점한다.
  • 잠금을 선점하지 않은 사용자가 기능을 실행했다면 기능 실행을 막아야한다.

DB를 이용한 LockManager 구현

잠금 정보를 저장하기 위한 테이블 생성 쿼리

create table locks (
  `type` varchar(255),
  id varchar(255),
  lockid varchar(255),
  expiration_time datetime,
  primary key (`type`, id)
) character set utf8;

create unique index locks_idx ON locks (lockid);

느낀점

확실히 선점 잠금과 비선점 잠금에 비해 확실하게 충돌을 방지할 수 있을 것 같다고 생각한다.

하지만 사용자 입장에서는 좋은 경험이 되지는 않을 것 같다.

오프라인 선점 방식은 데이터의 일관성이 아주 아주 중요한 상황에서 사용하면 좋을 것 같다.