Search
Duplicate
📒

[Database Study] 03-6. 낙관적, 비관적 락

상태
수정중
수업
Database Study
주제
Transaction
연관 노트
3 more properties
참고

동시성 제어

NOTE
DBMS가 다수의 사용자 사이에서 동시에 적용하는 다중 트랜잭션의 상호간섭 작용에서 Database를 보호하는 것을 의미한다.
일관성과 동시성은 서로 반비례한다..
동시성 제어 방법
Lock 기능
SET TRANSACTION 명령어

Optimisitc Lock(낙관적 잠금)

NOTE
DB의 Lock을 사용하지 않고 Version관리를 통해 애플리케이션 레벨에서 처리한다!
기존 A가 A+3이되어서 세션2의 Write가 실패한다.
대부분의 트랜잭션이 충돌하지 않는다고 가정하는 방법이다.
트랜잭션 커밋 전에는 충돌을 알 수 없다.

Pessimistic Lock (비관적 잠금)

NOTE
데이터를 읽는 시점에 Lock을 걸고, 트랜잭션이 완료될 때까지 이를 유지한다!
세션 1에서 이미 작업하고 있으므로, 세션2는 읽지 못한다. (데이터를 읽는 시점 락을건다.)
대부분의 트랜잭션이 충돌한다고 가정하는 방법이다.
SELECT 시점에 Lock을 거는 비관적 잠금은 동시성을 심각하게 떨어트릴 수 있어 waitnowait 옵션과 사용해야 한다.

Locking 메커니즘의 문제점

NOTE
읽기 작업과 쓰기 작업이 서로 방해를 일으키기 때문에 동시성 문제가 발생
데이터 일관성에 문제가 생기는 경우도 있어서 Lock을 더 오래 유지하거나 테이블 레벨의 Lock을 사용해야 하고, 동시성 저하가 발생한다.
⇒ 이러한 문제점을 해결하기 위해 MVCC(다중 버전 동시성 제어)가 탄생하게 되었다!

JPA의 낙관적 락, 비관적 락

NOTE
JPA는 데이터베이스에 대한 동시 접근으로부터 엔티티의 무결성을 유지하기 위해 동시성 메커니즘을 제공한다!
public void likePostByOptimisticLock(Long postId) { var post = postRepository.findById(postId, false).orElseThrow(); post.incrementLikeCount(); // 좋아요 증가에 대한 동시성문 }
Java
복사
Cmd를 활용해서 2개의 쓰레드로 동시에 진행한다.
낙관전 락(Optimistic Lock)
데이터 갱신 시, 충돌이 발생하지 않을 것이라는 가정하에 진행
비관적 락(Pessimistic Lock)
데이터 갱신 시, 충돌이 발생할 것이라는 가정을 두고 진행하는 락 기법

JPA 낙관적 락 구현(@Version 사용)

NOTE
DB의 Lock을 사용하지 않고, Entity의 버전을 통해 동시성을 제어한다!
@Getter @NoArgsConstructor @Entity public class Member { // Entity 요소 .. // 낙관적 락 구현 @Version private Long version; // ... }
Java
복사
@Version 애노테이션을 사용해서, 낙관적 락을 쉽게 구현할 수 있다.
1의 likeCount를 멀티쓰레드로 2번 증가시켰는데, 예외가 발생하고 1번만 적용됨
Entity가 변경될 떄 마다 version이 하나 씩 증가하며, Entity를 수정할 때 조회한 시점의 version과 일치하지 않으면 예외가 발생한다!
ObjectOptimisticLockingFailureException
‘최초 커밋만 인정하기 정책’을 구현할 수 있다!

참고

낙관적 락의 LockModeType을 변경할 수 있지만, @Version에 적용이 불가능.

JPA 낙관적/비관적 락 구현(@Lock 사용)

NOTE
@Lock을 이용해서 락을 걸 수 있다!
public interface MemberRepository extends JpaRepository<Member, Long> { // 비관적/낙관적 락 @Lock(LockModeType.PESSIMISTIC_WRITE) Optional<Member> findById(Long id); }
Java
복사
어떤 LockModType을 거는지에 따라 동작이 달라진다.
lock을 걸어서 동시성 문제가 사라짐!

LockModeType의 종류

PESSIMISTIC_READ
다른 트랜잭션에서 Read만 가능
PESSIMISTIC_WRITE
다른 트랜잭션에서 Read/Write 불가능
PESSIMISTIC_FORCE_INCREMENT
다른 트랜잭션에서 Read/Write 불가능, versioning 진행
OPTIMISTIC_LOCK
수정시가 아니라, 조회단계부터 version을 체크한다.
OPTIMISTIC_FORCE_INCREMENT
version를 수정하지 않아도 커밋시 자동으로 version을 증가시킨다.

낙관적 락 vs 비관적 락

NOTE

낙관적 락

장점
리소스 경쟁이 적고 lock으로 인한 성능저하가 적다.
단점
충돌 발생 시 처리해야 할 외부 요인이 존재한다.

비관적 락

장점
충돌 발생을 미연에 방지하고 데이터의 일관성을 유지할 수 있다.
단점
동시 처리 성능 저하 및 교착상태(DeadLock) 발생 가능성이 있다.