인프런 커뮤니티 질문&답변

흑후추님의 프로필 이미지
흑후추

작성한 질문수

스프링 DB 1편 - 데이터 접근 핵심 원리

DB 락 - 조회

비관적 락 질문드립니다.

해결된 질문

작성

·

776

·

수정됨

3

 

[질문 템플릿]

1. 강의 내용과 관련된 질문인가요? 예

2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예

3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예

[질문 내용]

JPA 책 16장 확인하고 질문이 생겨서 글 남깁니다.

강의에서 'for update'를 사용하는걸 보면 비관적 락인 'PESSIMISTIC_WRITE'방식인것같아요.

그런데 이게 'PESSIMISTIC_READ'랑 어떤 차이가 있는지 잘 모르겠어요..

검색해보니까 write가 읽기도 막는다고 적혀있는곳이 종종 보이는데,

강의에서는 for update하고 다른 트랜잭션에서 읽기가 정상적으로 된것같아서요..

제가 스프링에서 두 방식 설정해서 각각 실행시킨 다음에 mysql workbench에서 select문 실행시켰을때도 모두 문제 없이 읽혔어요

어떤 차이가 있는건가요?

답변 1

6

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 흑후추님

이런 부분은 데이터베이스 마다 다르게 동작합니다.

일반적으로 비관적 락의 경우 PESSIMISTIC_WRITE를 사용하고 select for update 구문으로 이해하시면 됩니다. select for update의 경우에도 데이터베이스에 따라서 다른 트랜잭션에서 데이터를 읽어갈 수 있습니다.

SELECT FOR UPDATE는 MySQL에서 공유하지 않는 잠금(non-shared lock)을 사용하여 선택된 행을 잠근다는 것을 의미합니다. 이 잠금이 걸린 동안, 다른 트랜잭션에서 이 행을 수정하거나, SELECT FOR UPDATE, SELECT ... LOCK IN SHARE MODE와 같은 또 다른 잠금을 시도하는 것은 불가능합니다.

하지만, SELECT 문을 일반적인 방식(즉, FOR UPDATE 또는 LOCK IN SHARE MODE 없이)으로 사용하는 다른 트랜잭션은 여전히 잠금이 설정된 행을 읽을 수 있습니다. 이러한 종류의 조회는 일관성있는 read(consistent read)로 불리며, 조회 시점의 스냅샷을 기반으로 데이터를 읽습니다.

그러나 이것은 MySQL의 격리 수준(isolation level)에 따라 달라집니다. 격리 수준이 SERIALIZABLE로 설정된 경우, 모든 SELECT 문은 암시적으로 LOCK IN SHARE MODE를 사용하게 되므로 SELECT FOR UPDATE로 잠긴 행을 읽을 수 없게 됩니다.

따라서, 다른 트랜잭션에서 SELECT FOR UPDATE로 잠긴 행을 읽을 수 있는지 여부는 사용 중인 격리 수준에 따라 달라집니다.

 

이런 이유로 보통 select for update를 적용해도 데이터를 읽을 수 있기 때문에 PESSIMISTIC_READ를 잘 사용하지는 않습니다.

PESSIMISTIC_READ의 경우 각각의 데이터베이스 메뉴얼 사용법을 읽어보시고 적용할 지 고민하셔야 합니다.

(일반적으로 잘 사용하지 않습니다.)

MySQL: lock in share mode

PostgreSQL:for share

감사합니다.

흑후추님의 프로필 이미지
흑후추

작성한 질문수

질문하기