[JPA] 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)
Spring

[JPA] 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)

728x90

JPA를 사용할때는 Transaction에 대한 격리 수준이 존재합니다. 여기서 @Transactional 어노테이션에 대해서 다루었었죠. 어노테이션의 기본값은 DB의 격리정책과 동일하게 가는 것으로 돼있는데, 대부분의 데이터베이스들은 ACID 원칙에서 격리성(Isolation)을 만족시키기 위해  READ COMMITED 수준을 사용합니다.

 

트랜잭션의 ACID 특성

  • 원자성 (Atomicity): 부분적으로만 실행되거나 중단되지않는 것을 보장
  • 일관성 (Consistency): 트랜잭션이 완료되면 일관적인 DB상태를 유지
  • 격리성 (Isolation): 트랜잭션 수행시 다른 트랜잭션이 끼어들지 못하도록 보장
  • 지속성(Durabuility): 성공적으로 수행된 트랜잭션은 영원히 반영

 

격리 수준에는 대표적으로 다음의 종류가 있습니다

  • READ UNCOMMITEED: 커밋되지 않은 데이터 읽을 수 있음 Dirty Read(커밋되지 않은 데이터 읽기) , Dirty Write (커밋되지 않은 정보 덮어쓰기) 가능 (거의 사용안함)
  • READ COMMITED: 커밋된 데이터만 읽을 수 있음, Read Skew(읽는동안 데이터 변경) 발생 가능
  • REPEATABLE READ: 트랜잭션 동안 같은 데이터를 읽게 보장, Lost Update(변경사항 유실) 발생 가능
  • SERIALIZABLE: 모든 트랜잭션을 순서대로 실행

격리 수준은 종류별로 높고 낮음이 존재하는데요, READ COMMITED 이상의 격리수준이 필요할때 비관적 락, 낙관적 락을 사용할 수 있습니다. 


비관적 락 (Pessimistic Lock)

  • 트랜잭션이 충돌한다고 미리 가정하고 우선 락을 겁니다. (비관적으로 생각하는거죠!)
  • DB가 제공하는 락 기능을 사용합니다
  • 데이터 수정시 즉시 트랜잭션 충돌을 알 수 있습니다

낙관적 락 (Optimistic Lock)

  • 트랜잭션 충돌이 발생하지 않는다고 가정합니다.
  • DB가 제공하는 락을 사용하지 않고 JPA 가 제공하는 version 관리 기능을 사용합니다.
  • 트랜잭션이 커밋되기 전까지는 트랜잭션의 충돌을 알 수 없습니다.

낙관적 락의 특징은 아래처럼 Version 관리 기능을 사용해야한다는 것인데요

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

    private String name;

    @Version // 버전 어노테이션 명시
    private Integer version;
{

예를들어 트랜잭션1이 데이터를 조회해서 수정중인데, 그 사이 트랜잭션2가 데이터를 수정했고 데이터의 version은 상승했습니다. 이후 트랜잭션1 이 수정작업을 끝내고 커밋을하면 버전의 불일치로 (더 낮은 버전으로 커밋) 트랜잭션1의 작업은 오류가 나게 됩니다.

https://devjem.tistory.com/28

위 그림처럼 버전관리를 통해 트랜잭션이 관리됩니다.

 

출처:
- [JPA] 비관적 락 , 낙관적 락
- [JPA] 낙관적 락이란?
728x90