작성
·
1.1K
·
수정됨
0
좋은 강의 너무 감사합니다.
강의를 보며 궁금한 점이 생겨서 질문 드립니다.
named lock을 통해 동시성 문제를 해결하는 예시를 보았을 때, 비관적 락과 무엇이 다른 것인지 큰 차이를 느끼지 못했습니다.
named lock이 비관적 락에 비해 가지는 장단점에 비해 찾아보니, timeout 설정이 좀 더 간편하다는 내용 말고는 유의미한 차이를 찾지 못했습니다.
(그러나 비관적 락 + queryhint 를 사용하면 비관적 락 사용 시에도 딱히 어려움 없이 timeout을 설정할 수 있었습니다.)
혹시 named lock이 비관적 락에 비해 지니는 장단점과, 어떤 경우에 비관적 락 대신 Named lock을 통해 분산락을 구현하시는지 궁금하여 질문드립니다.
답변 1
7
많은 분들이 비관적 락에는 타임아웃(timeout)을 걸 수 없어서 데드락의 위험이 있다고 하지만 동훈님 말씀대로 비관적 락에도 @QueryHint 또는 em.persist에 타임아웃 속성을 걸 수 있습니다.
@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout",value = "1000")})
@Query("update Member set m.name = :name where id = 1")
void update(@Param("name") String name);
우선 비관적 락은 for update 구문으로 레코드 레벨에 잠금을 겁니다. 이렇게 레코드 레벨에락을 걸어버리면 해당 태스크의 트랜잭션 뿐만 아니라 다른 태스크들을 처리하기 위한 커넥션들도 락이 걸린 레코드에 접근하지 못한다는 특징이 있습니다.
반면에 네임드 락의 경우 락의 대상이 테이블이나 레코드 또는 auto_increment와 같은 데이터베이스 객체가 아니라는 점입니다. 네임드 락은 단순히 사용자가 지정한 문자열(String)에 대해 획득하고 반납(해제)하는 잠금입니다.
그렇기 때문에 동시성이 발생하는 트랜잭션에 대해서 동시성 이슈를 안전하게 처리할 수 있으면서, 다른 태스크들을 처리하기 위한 커넥션에는 전혀 영향을 주지 않을 수 있다는 장점이 있어보입니다.
베베님 답변해주셔서 감사합니다.
베베님께서 말씀해주신 케이스 뿐만 아니라 update 작업이 아닌 insert 작업의 경우에는 기준을 잡을 레코드가 존재하지 않기때문에 비관적락을 사용할 수 없습니다.
이런 상황에서 동시성이슈를 해결하기 위하여 named lock 을 사용할 수 있습니다.
답변 정말 감사합니다.
이 예제에만 집중하다 보니, 말씀해주신 경우를 생각해보지 못했네요 ㅎㅎ..