해결된 질문
작성
·
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
감사합니다.