OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT

2024. 10. 22. 18:56Spring Boot/Spring Data JPA

LockModeType.OPTIMISTIC

LockModeType.OPTIMISTIC은 데이터베이스에서 사용하는 비관적 잠금과 대조되는 낙관적 잠금 전략입니다. 이 전략은 데이터의 동시성을 높이면서도 데이터의 무결성을 보장하기 위해 사용됩니다. 아래에서 LockModeType.OPTIMISTIC에 대해 설명하겠습니다.

OPTIMISTIC (낙관적 잠금)

정의

  • 낙관적 잠금은 데이터에 대한 작업을 수행할 때, 다른 트랜잭션이 해당 데이터를 수정하지 않을 것이라고 가정하는 방식입니다. 즉, 데이터의 변경을 시도할 때까지 잠금을 사용하지 않으며, 최종적으로 데이터베이스에 변경을 적용할 때 충돌 여부를 확인합니다.

사용 목적

  • 동시성 향상: 여러 트랜잭션이 동시에 같은 데이터에 접근할 수 있도록 하여 성능을 높입니다.
  • 충돌 감지: 데이터의 변경이 발생할 때, 충돌이 발생했는지 확인하여 필요시 롤백할 수 있습니다.

사용 방법

Spring Data JPA에서 LockModeType.OPTIMISTIC을 사용하려면 @Version 어노테이션을 사용하여 버전 관리 기능을 구현해야 합니다. 아래 예시는 OPTIMISTIC 잠금을 사용하는 방법을 보여줍니다.

예시: 낙관적 잠금 사용

  1. 엔티티 클래스에 버전 필드 추가
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Version;

@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @Version
    private Long version; // 낙관적 잠금을 위한 버전 필드

    // Getter와 Setter 생략
}
  1. 레포지토리에서 낙관적 잠금 사용
import org.springframework.data.jpa.repository.JpaRepository;
import javax.persistence.LockModeType;
import javax.persistence.Lock;
import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

    // 낙관적 잠금 적용
    @Lock(LockModeType.OPTIMISTIC)
    List<User> findByName(String name);
}

위의 코드에서 User 엔티티는 @Version 어노테이션을 통해 버전 필드를 추가하여 낙관적 잠금을 지원합니다. findByName 메서드는 LockModeType.OPTIMISTIC 잠금을 사용하여 호출될 때 데이터에 대한 낙관적 잠금이 적용됩니다.

OPTIMISTIC의 특징

  1. 성능: 낙관적 잠금은 비관적 잠금에 비해 성능이 좋습니다. 데이터에 대한 접근이 많은 환경에서 더 많은 트랜잭션이 동시에 처리될 수 있습니다.
  2. 충돌 감지: 데이터의 변경이 시도될 때, 버전 필드를 체크하여 다른 트랜잭션이 해당 데이터를 수정했는지를 확인합니다. 수정이 발생했다면 OptimisticLockException 예외가 발생합니다.
  3. 트랜잭션 관리: 낙관적 잠금은 트랜잭션이 완료되기 전에 데이터의 충돌 여부를 확인할 수 있어, 실패 시 트랜잭션을 롤백할 수 있습니다.

LockModeType.OPTIMISTIC은 데이터의 동시성을 향상시키면서도 데이터 무결성을 유지할 수 있는 유용한 도구입니다. 일반적으로 데이터 변경 충돌이 드물게 발생하는 환경에서 효과적이며, 성능을 중요시하는 경우에 적합합니다.

LockModeType.OPTIMISTIC_FORCE_INCREMENT

LockModeType.OPTIMISTIC_FORCE_INCREMENT는 JPA에서 제공하는 잠금 모드 중 하나로, 낙관적 잠금과 함께 버전 필드를 강제로 증가시키는 기능을 제공합니다. 이 잠금 모드는 기본적으로 LockModeType.OPTIMISTIC와 유사하지만, 특정 상황에서 더 엄격한 제어를 필요로 할 때 사용됩니다.

OPTIMISTIC_FORCE_INCREMENT 정의

  • 낙관적 잠금 + 강제 버전 증가: LockModeType.OPTIMISTIC_FORCE_INCREMENT는 데이터의 상태를 변경하기 위해 낙관적 잠금을 사용하면서, 항상 엔티티의 버전 필드를 증가시킵니다. 이는 해당 엔티티가 수정된 것으로 간주되며, 다른 트랜잭션이 이를 수정할 수 없도록 잠금을 걸어주는 효과가 있습니다.

사용 목적

  • 동시성 제어: 다른 트랜잭션에서 수정할 수 없도록 보장하고, 동시에 데이터의 변경이 발생했을 때 충돌을 방지합니다.
  • 버전 관리: 엔티티가 수정되었다고 간주하므로, 충돌 감지 및 데이터 무결성을 강화할 수 있습니다.

사용 방법

Spring Data JPA에서 LockModeType.OPTIMISTIC_FORCE_INCREMENT를 사용하려면, 쿼리 메서드에 @Lock 어노테이션을 적용하면 됩니다.

예시: OPTIMISTIC_FORCE_INCREMENT 사용

  1. 엔티티 클래스에 버전 필드 추가
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Version;

@Entity
public class Product {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private double price;

    @Version
    private Long version; // 낙관적 잠금을 위한 버전 필드

    // Getter와 Setter 생략
}
  1. 레포지토리에서 OPTIMISTIC_FORCE_INCREMENT 사용
import org.springframework.data.jpa.repository.JpaRepository;
import javax.persistence.LockModeType;
import javax.persistence.Lock;
import java.util.Optional;

public interface ProductRepository extends JpaRepository<Product, Long> {

    // OPTIMISTIC_FORCE_INCREMENT 적용
    @Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
    Optional<Product> findById(Long id);
}

위의 예제에서 findById 메서드는 LockModeType.OPTIMISTIC_FORCE_INCREMENT 잠금을 사용하여 호출될 때마다 엔티티의 버전이 증가하게 됩니다. 이는 해당 엔티티가 변경되었다고 간주하며, 다른 트랜잭션이 이를 수정하는 것을 방지합니다.

OPTIMISTIC_FORCE_INCREMENT의 특징

  1. 버전 증가 보장: 이 잠금을 사용할 경우, 데이터가 수정되지 않았더라도 버전 필드가 증가합니다. 이는 무조건적으로 버전 관리를 강화합니다.
  2. 동시성 유지: 다른 트랜잭션이 해당 데이터를 동시에 수정하지 못하게 하여, 데이터의 일관성을 더욱 강하게 보장합니다.
  3. 성능 고려: 버전이 항상 증가하기 때문에, 불필요한 버전 증가가 발생할 수 있어 성능에 영향을 줄 수 있습니다. 따라서 사용 시 주의가 필요합니다.

LockModeType.OPTIMISTIC_FORCE_INCREMENT는 낙관적 잠금을 사용하는 동시에 데이터의 버전 필드를 강제로 증가시키는 기능을 제공합니다. 이는 데이터 충돌을 방지하고, 데이터 무결성을 보장하는 데 유용하지만, 불필요한 버전 증가로 인한 성능 저하를 고려해야 합니다

'Spring Boot > Spring Data JPA' 카테고리의 다른 글

JPA Query Methods  (0) 2024.10.23
Auditing  (0) 2024.10.22
PESSIMISTIC_READ, PESSIMISTIC_WRITE  (0) 2024.10.22
Locking  (0) 2024.10.22
Transactionality  (0) 2024.10.22