본문 바로가기
카테고리 없음

230413 TIL

by hbIncoding 2023. 4. 14.

1.  Lock 옵션에 따른 실험 결과

 1)Lock 옵션 종류와 설명

   ㄱ. Optimistic

  • NONE : 별도의 옵션을 사용하지 않아도 Entity에 @Version이 적용된 필드만 있으면 낙관적 잠금이 적용됩니다.
  • OPTIMISTIC(read) : Entity 수정시에만 발생하는 낙관적 잠금이 읽기 시에도 발생하도록 설정합니다.
    읽기시에도 버전을 체크하고 트랜잭션이 종료될 때까지 다른 트랜잭션에서 변경하지 않음을 보장합니다.
    • 이를 통해 diry read와 non-repeatable read를 방지
  • OPTIMISTIC_FORCE_INCREMENT(write) : 낙관적 잠금을 사용하면서 버전 정보를 강제로 증가시키는 옵션

  ㄴ. Pessimistic

  • PESSIMISTIC_READ : dirty read가 발생하지 않을 때마다 공유 잠금(Shared Lock)을 획득하고 데이터가 UPDATE, DELETE 되는 것을 방지 할 수 있습니다.
  • PESSIMISTIC_WRITE : 배타적 잠금(Exclusive Lock)을 획득하고 데이터를 다른 트랜잭션에서 READ, UPDATE, DELETE 하는것을 방지 할 수 있습니다.
  • PESSIMISTIC_FORCE_INCREMENT : 이 잠금은 PESSIMISTIC_WRITE와 유사하게 작동 하지만 @Version이 지정된 Entity와 협력하기 위해 도입되어 PESSIMISTIC_FORCE_INCREMENT 잠금을 획득할 시 버전이 업데이트 됩니다.

 2)실험 결과 요약

  • 현재 서비스에서는 PESSIMISTIC_WRITE만 제대로 작동한다.
  • Optimistic은 성능은 좋지만 주문이 폭주하는 경우 트랜잭션을 시작할 때 저장한 버전 값과 트랜잭션이 끝나고 난 후 체크한 버전값이 다른 경우가 많은데 이 때 잘 작동하지 않는다. 따라서 진행하는 서비스에는 적합하지 않다.
  • 또한 Force_Increment 옵션의 경우 지원하는 DB의 종류가 정해져있는데, 현재 사용중인 mysql에서는 사용이 불가능하다.
  • PESSIMISTIC_READ는 어떤 트랜잭션이 수정중일 때 다른 트랜잭션에서 읽기는 가능하다. 하지만 현재 실험에서는 모든 트랜잭션들이 수정하고자 하기 때문에 적합하지 않다.
  • PESSIMISTIC_WRITE를 사용한 결과

2.  Redisson Distribution Lock

  • Transaction이 Lock을 점거하고 있다는 정보를 redis 서버(캐시 서버)에 올려서, 분산된 서버에서 하나의 DB를 조회하고 수정할 때 사용하기에 적절한 방법이다.
  • 아래 자세히 설명하겠지만, 요청 Thread를 순서대로 처리한다는 보장이 없다는 단점이 있다.

 1)실험 결과 요약

  • 잘 작동하지만 아래와 같이 주문 id가 순서대로 되어있지 않다. 즉 요청된 Thread를 순서대로 처리하지 않는다.
    • 이러한 단점을 해결하기 위해선 Redisson Distribution Lock 이 아니라 Redisson Fair Lock을 사용해한다.
    • 하지만 이 경우에는 DeadLock 문제가 발생할 가능성이 있다.
  • 순서대로 처리하지 않는 이유는 먼저 Thread가 lock을 선점한 동안 여러개의 Thread가 대기중일 때, 먼저 선점한 Thread가 트랜잭션을 완료 한 이후 어떤 Thread가 lock을 점유할지 모르기 때문이다.
    • Thread1번이 3초가 걸리는 Transaction을 진행중이다.
    • 이때 Thread 2번 부터 10번까지 대기를 한다. 
    • 2~10번까지 Thread1 이 끝날때 까지 계속 lock 점거를 요청한다.
    • 2~10번이 계속 요청하기 때문에 1번 종료 시점에 누가 점유하게 될지 장담할 수 없다.

 

3.  참조

 1)mysql 데이터 테이블 기반 테스트 코드 작성하기 : https://dev-coco.tistory.com/85

 

[Spring Boot] MySQL & JPA 연동 및 테스트 (Gradle 프로젝트)

SpringBoot에서 MySQL 그리고 Spring Data JPA를 연동하는 방법에 대해 알아보도록 하겠습니다. 1. 프로젝트에 의존성 추가하기 build.gradle에 의존성을 아래와 같이 추가해줍니다. dependencies { implementation 'my

dev-coco.tistory.com

 2)LockModeType : https://velog.io/@lsb156/JPA-Optimistic-Lock-Pessimistic-Lock

 

JPA의 낙관적 잠금(Optimistic Lock), 비관적 잠금(Pessimistic Lock)

요청이 많은 서버에서 여러 트랜잭션이 동시에 같은 데이터에 업데이트를 발생시킬 경우에 일부 요청이 유실되는 경우가 발생하여 장애로 이어질 수 있습니다. 이를 위해 동시 읽기/업데이트

velog.io

 3)Redisson분산락 : https://velog.io/@hgs-study/redisson-distributed-lock

 

Redisson 분산락을 이용한 동시성 제어

Redis 클라이언트인 Redisson 분산락(Distributed Lock)을 이용해서 동시성을 제어하는 포스팅을 진행해봤습니다 (예제 포함)

velog.io