서론
지금 진행중인 프로젝트에서 마이크로서비스 아키텍처를 도입하기로 결정했습니다. 핀테크를 주제로 하는 만큼 결제, 조회 등 서비스에 필요한 중요한 기능들이 매우 밀접하게 맞물려 있는데, 저에게 익숙한 기존의 모놀리식 아키텍처가 아닌 마이크로서비스 아키텍처를 준비하게 되면서 여러 가지 발생할 수 있는 문제들에 대해 학습할 수 있었습니다.
그 중 동시성 제어 문제가 가장 관심이 갔는데요, 오늘의 주제는 이 부분에 대해서 다루고자 합니다.
비관적 락 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 환경에서 유용하게 쓰이는 다른 패턴과 함께 자세하게 소개해보겠습니다!!
'Spring' 카테고리의 다른 글
[Security] 유잔씨의 Refresh Token 사용법 (1) | 2024.09.08 |
---|---|
상속을 이용해 Entity 구성하기 (0) | 2024.09.08 |
간단하게 알아보는 Spring Cloud Config (0) | 2024.09.01 |
븟츠의 동시성 이슈 해결 방법 (0) | 2024.09.01 |
Spring Security Architecture (Spring MVC 기반) (0) | 2024.08.25 |