1 minute read

  • DB의 동시 액세스의 대한 주제이다.

낙관적 락, 비선점 락(Optimistic Lock)

  • 사용자들이 같은 데이터를 동시에 수정하지 않을 것이라고 가정해 Lock을 설정하지 않는다.
    • 락을 해야하는 상황의 발생이 일어나면 그때 대응하자, 자원을 선점 시키지 말자. 라는 의미이다.
  • JPA가 제공하는 버전 관리 기능(@Version)을 사용해 “Application Level”에서의 Lock을 거는 것이다.
@Version
private Integer version;
update {table}
set
  {column} = ?,
  version = ?     (버전 증가)
where
  id = ?
  and version = ? (버전 비교)
  • 해당 자원을 read 할 때 version 정보도 함께 가져온 후 수정시 where 조건으로 읽어올 때 가져온 버전과 DB의 버전이 같은지 확인을 하고 같다면, 커밋하고 자동으로 버전을 증가 시킨다.
  • 누군가 내가 수정 하는 사이에 건드리지 않았다면 정상적으로 업데이트가 될 것이고, 그렇지 않다면 적용된 로우가 0 으로 리턴 될 것이다.
    • JPA(hibernate)의 경우에는 이런 상황에서 Optimistic Lock Exception을 던져 어플리케이션 단에서 충돌이 발생 했음을 인지 가능하며, 로직으로 Exception을 처리할 수 있다.

비관적 락, 선점 락(Pessimistic Lock)

  • 자원에 대한 동시 요청이 발생 할 것이고, 그래서 일관성에 문제가 생길 것이다. 라고 비관적으로 생각하고 이를 방지 하기 위해 자원을 선점 하도록 하는 방식이다.
  • 따라서 한 사용자가 데이터를 “읽는 시점”에 “DB수준”에서 Lock을 걸고 조회 또는 갱신처리가 완료될 때까지 이를 유지한다.
    • SELECT FOR UPDATE(업데이트를 위한 조회) 를 사용하는 방식으로 한 자원을 누군가 읽어가서 변경하고 있다면 다른 사용자는 해당 사용자가 업데이트를 마칠 때 까지 해당 자원을 사용하지 못한다.
    • 자칫 시스템 동시성을 심각하게 떨어뜨릴 우려가 있다.
  • 비관적 락에서 사용하는 Lock의 종류
entityManager.find(Student.class, 1L, LockModeType.PESSIMISTIC_WRITE, properties); // 비관적 락의 일반적 옵션을 뜻함(쓰기 락)
select {column...}
from student
where ... for update

Categories:

Updated:

Comments