[동시성] 낙관적 락 & 비관적 락

SIK407·2025년 6월 24일

Backend

목록 보기
6/10
post-thumbnail

아니 낙관적 & 비관적이 개발용어가 아닐텐데..
검색하면 싹다 그냥 DB Lock에 대한 자료다. ㅋㅋㅋㅋㅋㅋㅋㅋ


◽ 서론

[동시성] synchronized
이 글을 보고 오길 추천한다.

간단하게 저 글을 요약하면,
synchronized는 Java에서 메소드 자체를 Lock을 하는 예약어다.

하지만 다중서버일 때는 컨트롤할 수 없기에, DB Lock을 주로 사용한다.

◽ Lock?

공유 자원을 하나의 스레드가 사용하고 있을 때,
다른 스레드가 공유 자원을 사용하지 못 하도록 제한

전역 변수, DB 값
어디서나 누구나 접근할 수 있는 자원을 공유 자원이라고 말한다.

A가 Good 변수를 3으로 가져오고, +1 연산을 진행했다.
이걸 DB에 Commit하기 직전 그사이에!

B가 DB에서 Good 변수를 가져온다.
그럼 B도 똑같이 3을 가져오게 된다.

Good이란 공유자원을 Commit이 되기 전,
접근해 버려서 경쟁상태(Race Over)가 발생해버렸다.

저 상태로 B도 +1 연산을 진행해도, 결국 DB엔 4로 Commit이 된다.

그래서 DB에 A가 접근하는 동안,
Lock을 걸어 다른 사람(스레드)이 사용하지 못하도록 제한해야 한다.


◽ Lock 전략

제목에 적혀있는 낙관적 락, 비관적 락을 알아보자.

1. 비관적 락(pessimistic lock)

"데이터는 언젠가 다른 트랜잭션과 충돌할 거야"
미리 Lock을 걸어버려서 다른 트랜잭션의 접근을 막는 방식

비관적의 사전적인 정의는 "앞으로의 일이 잘 안될거라 봄" 이다.
충돌이 좋은 현상은 아니지 않는가?

그걸 DB 수준의 Lock을 걸어서, 공유자원의 동시 접근을 막는다.

(DB Lock의 종류는 밑에...)

2. 낙관적 락(Optimistic Lock)

"충돌은 잘 안 날 거야. 일단 접근하고, 나중에 확인만 하자."
트랜잭션 커밋 직전, 버전(version)을 비교해서 충돌을 감지하는 방식

낙관적 락은 DB 수준의 Lock이 아닌,
Application Level에서 개발자가 직접 구현하는 전략이다.

그러니까 나로 예시를 들면, Spring에서 직접 구현해야 된다.

@Entity
public class Post {
    @Id
    private Long id;

    private String content;

    @Version  // 낙관적 Lock
    private Integer version;
}

이런식으로 @Version 어노테이션을 입력해 놓으면 된다.

UPDATE post SET content = '바뀐내용', version = version + 1
WHERE id = 1 AND version = 3

그러면 내부적으로 이러한 Query가 만들어진다고 한다.

이미 누가 바꿔서 version이 4가 되었을 경우, OptimisticLockingFailureException이란 에러가 발생한다.

하지만 낙관적 락은 Update 하기 전, 조회(Select) 하면서 Lock을 거는 작업이 필요없다.
따라서 성능적으로 비관적 락보다 더 좋다.


◽ DB Lock 종류

1. 공유 락(Shared Lock)

데이터를 변경하지 않는 Read에 대해 주어지는 Lock

Read Lock이라고도 불리며, Shared의 약자 S를 따서 S-Lock 이라고도 한다.

다른 트랜잭션이 Lock을 한 객체를 읽고, 다른 공유 락을 생성하는 것은 허용한다.
그러나 쓰기, 베타 락을 생성하는 것을 허용하지 않는다.


예) A가 1번 레코드에 S-Lock 걸었음.

B가 1번 레코드에 S-Lock 걸었음 (✅)
B가 1번 레코드에 X-Lock 걸었음 (❌)



2. 베타 락(Exclusive Lock)

동일한 행에 다른 트랜잭션을 생성하는 것을 허용하지 않는 Lock

Write Lock으로도 불리며, X-Lock 이라고도 한다.

다른 트랜잭션에서 Lock을 생성할 수 없기에, Read, Write 둘 다 불가능하다.
베타락이 걸린 트랜잭션은 독점권을 얻게 된다.

3. 정리) 공유 락 & 베타 락

공유 락과 베타 락의 핵심은 Lock 호환 여부라고 한다.
(편의를 위해 락을 단어에서 뺐다)

공유공유를 허용하기 때문에 Read가 가능하고, 쓰기가 불가능하다.
베타Read, Write 둘 다 불가능하다.

(단, SERIALIZABLE 격리 수준은 Lock과 별개로 전부 다 읽기, 쓰기 전부 안된다.)


◽ 여담

인생은 낙관적으로!

profile
감자 그 자체

0개의 댓글