[TIL] 낙관적 락, 비관적 락
소프트웨어 개발에서 데이터 일관성을 유지하는 것은 매우 중요하다. 데이터의 일관성을 유지하기 위해 중요한 것은 바로 '동시성'을 제어하는 것이다. 동시성을 제어하는 두 가지 주요 락킹 메커니즘으로, 낙관적 락(Optimistic Locking)과 비관적 락(Pessimistic Locking)이 있다.
이번 포스팅에서는 낙관적 락과 비관적 락의 개념과 원리, 장단점에 대해 정리하고자 한다.
낙관적 락
낙관적 락은 충돌이 발생할 것이라고 "낙관적"으로 가정하는 것이다. 다시말해, 충돌이 발생할 가능성이 적다고 판단하고 실제로 충돌이 발생했을 때만 대응하겠다는 메커니즘인 것이다. 따라서, 데이터베이스에 대한 변경이 드물게 발생하고, 충돌 가능성이 낮은 환경에서 유용하다.
원리
낙관적 락은 데이터를 읽을 때는 락을 걸지 않고, 데이터를 업데이트할 때만 이전 데이터와 현재 데이터를 비교하여 충돌 여부를 판단한다. 이 방식을 사용할 경우, 상대적으로 데이터베이스의 성능 저하를 최소화하고 동시성을 높이는 데 유리하다.
장단점
낙관적 락은 데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 변경할 수 있기 때문에 성능이 좋고, 데드락(Deadlock) 발생 가능성이 낮다는 장점이 있다. 하지만, 낙관적 락은 충돌이 발생했을 때, 충돌 발생 시점부터 트랜잭션을 다시 시작해야 하기 때문 데이터를 다시 읽고, 업데이트해야 하는 추가 작업이 필요하다는 단점이 있다.
구현 방법
낙관적 락을 구현하는 방법 중 하나는 버전 번호를 사용하는 것이다. 데이터가 업데이트될 때마다 버전 번호를 증가시키고, 업데이트 시점에 버전 번호를 검사하여 충돌을 감지한다.
아래의 예시는, JPA에서 제공되는 Version 키워드를 이용해 낙관적 락을 구현한 사례이다.
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx;
private String contents;
@ColumnDefault(value="0")
private Integer likesCount;
@Version
@ColumnDefault(value="0")
private Integer version;
@OneToMany(mappedBy = "post")
List<Likes> likes = new ArrayLIst<>();
public void addLikesCount() {
this.lickesCount = this.likesCount + 1;
}
```
생략
```
}
낙관적 락은 성능이 중요하고, 충돌이 낮은 시스템에 적합하다.
비관적 락
비관적 락은 충돌이 발생할 것이라고 "비관적"으로 가정하는 것이다. 다시말해, 데이터의 충돌이 발생할 것이라고 예상하고, 데이터를 처음부터 잠그는 방식으로 충돌을 방지하는 메커니즘인 것이다. 따라서, 데이터에 대한 변경이 자주 발생하고, 충돌 가능성이 높은 환경에서 선호된다.
원리
비관적 락은 데이터의 일관성을 유지하는 데 초점을 맞추고 있기 때문, 데이터를 읽을 때부터 해당 데이터에 대한 락을 걸어 다른 트랜잭션이 해당 데이터를 변경할 수 없게 한다.
장단점
비관적 락은 데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 변경할 수 없기 때문에 데이터의 일관성을 보장한다는 장점이 있다. 하지만, 비관적 락의 경우, 상대적으로 DB 성능 저하와 데드락 발생 가능성이 높다는 단점이 있다. 왜냐하면 데이터에 대한 락을 걸어두면, 다른 트랜잭션이 해당 데이터에 접근할 수 없기 때문이다.
구현 방법
비관적 락을 구현하는 방법 중 하나는 데이터베이스의 락 기능을 사용하는 것이다. 데이터를 읽을 때 SELECT FOR UPDATE와 같은 쿼리를 사용하여 데이터에 대한 락을 걸 수 있다. 아래의 예시는, mariaDB 서버를 이용해 비관적 락을 구현하는 방식이다.

+) LOCK의 종류
- PESSIMISTIC_WRITE : 다른 트랜잭션이 읽기 X, 쓰기 X
- PESSIMISTIC_READ : 다른 트랜잭션이 읽기 O, 쓰기 X
비관적 락은 데이터의 일관성이 중요하고, 충돌 가능성이 높은 금융 시스템과 같은 환경에 적합하다.