개발

동시성 제어 (1편) 본문

CS/스프링

동시성 제어 (1편)

쇼팽리스트 2024. 11. 28. 12:56

서론

지금 진행중인 프로젝트에서 마이크로서비스 아키텍처를 도입하기로 결정했습니다. 핀테크를 주제로 하는 만큼 결제, 조회 등 서비스에 필요한 중요한 기능들이 매우 밀접하게 맞물려 있는데, 저에게 익숙한 기존의 모놀리식 아키텍처가 아닌 마이크로서비스 아키텍처를 준비하게 되면서 여러 가지 발생할 수 있는 문제들에 대해 학습할 수 있었습니다.

그 중 동시성 제어 문제가 가장 관심이 갔는데요, 오늘의 주제는 이 부분에 대해서 다루고자 합니다.

비관적 락 VS 낙관적 락

 

비관적 락(Pessimistic Locking)

 

개념과 특징

비관적 락 데이터 충돌이 빈번하게 발생하는 환경에서 데이터 일관성을 유지하기 위해 유용하게 사용할 수 있습니다. 데이터에 대해 Lock을 미리 걸어 트랜잭션이 종료되어 명시적으로 Lock이 해제되기 전 까지는 다른 트랜잭션이 해당 데이터에 접근할 수 없도록 합니다.

데이터에 Lock이 걸려 있는 동안에는 다른 트랜잭션은 Lock이 해제될 때 까지 기다려야 하므로 성능이 충돌이 빈번하게 발생하지 않는 경우 성능이 저하될 가능성이 높습니다.

Transaction 1이 수행되고 Commit이 된 후 에 Lock 해제가 되고 대기하고 있던 Transaction 2가 수행이 됩니다.

 

 

 

스프링 구현

public interface ProductRepository extends CrudRepository<Product, Long> {

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("SELECT p FROM Product p WHERE p.id = :id")
    Product findByIdWithLock(Long id);
} 

 

비관적 락의 구현은 @Lock 어노테이션과 LockModeType.PESSMISTIC_WRITE를 사용하여 쉽게 구현할 수 있습니다. @Lock 어노테이션은 메소드에 적용되어 해당 SQL구문을 Lock으로 보호하여 다른 트랜잭션이 동시에 수행되지 못하도록 합니다.

 

낙관적 락(Optimistic Locking)

 

개념과 특징

낙관적 락 데이터가 변경될 가능성이 낮은 환경에서 데이터 일관성을 유지하기 위해 유용하게 사용할 수 있습니다. 데이터베이스에서 제공하는 Lock을 사용하지 않고, JPA에서 제공하는 @Version 어노테이션이 제공하는 버전 정보를 사용하여 동시성을 제어합니다. 

 

 

 

 

스프링 구현

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private int quantity;

    @Version
    private Long version; // 버전 필드를 추가합니다.
}

 

@Version

해당 어노테이션을 통해 엔티티가 변경될 때마다 엔티티의 version 필드가 자동으로 값이 증가하게 됩니다. 트랜잭션이 커밋이 될 때 데이터베이스에 저장된 version 값과 현재 트랜잭션에서 증가한 version 필드의 값과 비교하여 동시성을 제어합니다. 두 version 값이 다른 경우 트랜잭션이 롤백됩니다.

 

사가 패턴(Saga Pattern)

기존의 모놀리식 아키텍처에서는 데이터의 동시성을 제어할 때 관계형 데이터베이스에서 제공하는 Lock과 트랜잭션을 유용하게 사용할 수 있었습니다. 하지만 MSA 환경과 같은 분산 시스템에서 트랜잭션의 주체가 데이터베이스가 아닌 서비스가 되어 데이터의 일관성을 유지하며 동시성을 제어하는 패턴입니다. 물론 Saga Pattern에서도 각 서비스의 로컬 데이터베이스에서는 여러 Lock을 사용해서 동시성을 제어하며 데이터의 일관성을 유지합니다.

해당 패턴에 대한 자세한 소개는 MSA 환경에서 유용하게 쓰이는 다른 패턴과 함께 자세하게 소개해보겠습니다!!