본문 바로가기

Lock

@정소민fan2025. 9. 15. 18:40

돌아온 락 페스티벌~~~ 이 아니라

데이터베이스의 락에 대해서 알아보자

비관적 락

충돌이 잦을 것으로 생각되는 데이터에 걸어두는 락이다. 일반적으로 사용되는 락이며, 데이터베이스에서 자체적으로 제공된다.

읽는 시점부터 트랜잭션이 끝날때까지 락을 걸어둔다.

따라서 데이터 정합성이 잘 보장되지만, 락으로 인해 다른 트랜잭션이 대기해야하므로 성능이 떨어질 수 있다.

충돌을 애초부터 막아두는 전략이다.

 

비관적 락 내에서도 두가지로 나뉘는데, S락과 X락이 있다.

S락

데이터를 조회하는 동안, 다른 트랜잭션이 데이터를 변경하지 못하게 막는다.

특징으로는 S락이 걸려있는 데이터에는 다른 트랜잭션도 S락을 걸어서 조회할 수 있다는 것이다.

하지만 S락이 걸려있는 동안은 X락은 걸 수가 없다. 조회하는 동안 데이터는 변경할 수 없다.

X락

데이터를 변경하는 동안, 다른 트랜잭션이 데이터를 읽지도, 변경하지도 못하게 막는다.

하나의 데이터에는 오직 하나의 X락만 걸 수 있고, 걸려있는 동안은 S락도 걸수가 없다.

낙관적 락

실제 데이터베이스의 락을 사용하지 않고, 애플리케이션 레벨에서 버전 관리 기능을 통해 구현되는 락이다.

데이터를 읽을 때 해당 데이터의 버전 정보를 읽고, 사용자 A가 작업을 마치고 데이터를 업데이트하려고 하면, 그 때 다시 데이터의 버전 정보를 읽어서 작업을 시작하기 전에 버전과 같은지 확인한다. 

비관적 락을 사용하지 않았기 때문에, 다른 사용자 B가 데이터를 변경할 수 있다. 변경하면서 데이터의 버전을 1 증가시키게 되면, 트랜잭션 A가 버전을 확인할 때, 이전의 버전과 다르기 때문에 데이터 정합성이 깨졌다고 판단하고, 작업을 재시도하거나 예외를 발생시키게 된다.

낙관적 락은 데이터를 직접 잠그지 않으므로 동시성이 유리해 성능이 좋다.

 

낙관적 락은 수정이 잦지 않고, 읽기 작업이 많은 곳에 사용된다.

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {

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

    private String name;

    private int stockQuantity;

    @Version
    private Long version;
    
}

이런 식으로 사용하면 될 것 같다. 롤백이 발생할 때는 ObjectOptimisticLockingFailureException이 발생하기 때문에, 비즈니스 로직에서 해당 예외를 감지하여 처리하는 로직이 따로 필요하다.

'DB' 카테고리의 다른 글

정규화와 반정규화  (0) 2025.09.24
트랜잭션 격리수준  (1) 2025.09.03
정소민fan
@정소민fan :: 코딩은 관성이야

코딩은 관성적으로 해야합니다 즐거운 코딩 되세요

목차