20241223 TIL : DB Lock

MCS·2024년 12월 23일

TIL

목록 보기
30/45

오늘 학습한 내용

  • DB Lock
    • DB Lock의 종류
    • 비관적 락과 낙관적 락의 동작 방식

DB Lock

DB Lock은 데이터베이스에서 여러 트랜잭션이 동시에 같은 데이터에 접근할 때, 데이터의 무결성(일관성)을 보장하기 위해 사용되는 메커니즘이다.
한 트랜잭션이 특정 데이터에 접근해 작업을 하고 있을 때, 다른 트랜잭션이 이에 접근할 수 없도록 잠근다.

DB Lock의 종류

공유 락(Shared Lock)

데이터베이스에서 데이터를 읽을 때 사용되며, 여러 트랜잭션이 동시에 같은 데이터를 읽을 수 있지만, 공유 락이 걸린 동안에는 데이터를 수정할 수 없다. 데이터를 조회하는 시점에 발생하며, 공유 락은 DB에서 자동 설정된다.

배타 락 (Exclusive Lock)

배타 락은 데이터를 수정할 때 사용되며, 배타 락이 걸린 데이터는 다른 트랜잭션이 읽거나 수정할 수 없다. 한 트랜잭션이 배타 락을 획득하면 다른 모든 트랜잭션은 해당 데이터에 접근할 수 없다(조회, 수정, 삭제 등 모두 불가능). 데이터를 수정하는 시점에 발생하며, 배타 락은 DB에서 자동 설정된다.

비관적 락(Pessimistic Locking)

비관적 락은 데이터를 읽을 때부터 락을 걸어 다른 트랜잭션이 접근하지 못하도록 하는 방식이며, 데이터의 충돌 가능성이 높을 때 유용하다. 데이터를 조회하는 시점에 발생하며, 비관적 락은 개발자가 직접 설정해야 한다.

낙관적 락(Optimistic Locking)

낙관적 락은 데이터를 수정하기 전까지 락을 걸지 않고, 수정 시점에만 충돌을 확인하는 방식이며, 주로 버전 컬럼을 통해 데이터의 버전 번호를 사용하여 동시성 문제를 해결한다. 낙관적 락은 개발자가 직접 설정해야 한다.

명명된 락(Named Lock)

명명된 락은 데이터베이스에서 특정 이름으로 락을 설정하여, 동시에 하나의 프로세스만 특정 리소스에 접근하도록 하는 방식이다. 주로 특정 리소스나 작업에 대한 접근을 직관적으로 제어하기 위해 사용된다. 명명된 락은 개발자가 DB에서 직접 설정해야 한다.

분산 락(Distributed Lock)

분산 락은 여러 시스템이나 인스턴스에서 동시에 동일한 자원에 접근할 때, 자원의 일관성을 유지하기 위해 사용되는 방식이며, Redis와 같은 분산 시스템을 사용하여 구현한다.

비관적 락과 낙관적 락의 동작 방식

비관적 락의 동작 방식

  • 비관적 락은 데이터에 대한 접근을 제어하기 위해 사용된다. 데이터베이스에서 특정 행(row)이나 테이블에 대해 락을 걸어, 다른 트랜잭션이 동시에 동일한 데이터에 접근하거나 수정하지 못하도록 한다.
  • 락의 종류:
    • PESSIMISTIC_READ: 읽기 락(Shared Lock)을 설정하여 다른 트랜잭션이 해당 데이터를 읽을 수는 있지만, 수정은 할 수 없도록 한다.
    • PESSIMISTIC_WRITE: 쓰기 락(Exclusive Lock)을 설정하여 다른 트랜잭션이 해당 데이터를 읽거나 수정하지 못하도록 한다.
  • DB 레벨에서의 락 동작:
    • 락 설정: 비관적 락을 사용하면 SQL 쿼리나 트랜잭션이 데이터베이스에 접근할 때 락이 설정된다. 예를 들어, PESSIMISTIC_WRITE 락을 설정하면, 해당 데이터에 대한 모든 읽기 및 쓰기 작업이 락이 해제될 때까지 대기한다.
    • 락 해제: 락은 일반적으로 트랜잭션이 종료되거나 커밋될 때 해제된다. 트랜잭션이 커밋되면 락이 해제되어 다른 트랜잭션이 해당 데이터에 접근할 수 있게 된다. 트랜잭션이 롤백되는 경우에도 락이 해제된다.

비관적 락은 데이터 일관성 및 무결성을 유지하는 데 매우 유용하며, 데이터 일관성과 무결성이 매우 중요한 은행 시스템과 같은 환경에서 자주 사용된다.
단, 락이 설정된 동안 다른 트랜잭션이 대기해야 하고 데드 락 문제가 발생하는 등 성능에 문제가 있을 수 있기 때문에 적절하게 사용해야 한다.

낙관적 락의 동작 방식

  • 낙관적 락의 동작방식
    • 낙관적 락(Optimistic Lock)은 트랜잭션 간의 충돌을 최소화하고 성능을 향상시키기 위해 사용된다.
    • 비관적 락이 데이터베이스 레벨에서 락을 걸어 다른 트랜잭션의 접근을 차단하는 방식이라면, 낙관적 락은 데이터베이스 락을 사용하지 않고, 대신 데이터가 변경되었는지 확인하여 충돌을 처리하는 방식이다.
    • 버전 관리:
      • 낙관적 락에서는 보통 version이라는 필드를 엔티티에 추가한다 JPA를 사용한다면 @Version 어노테이션을 선언해 사용할 수 있다. 이 필드는 해당 엔티티의 수정 횟수를 추적하는 역할을 한다.
      • 트랜잭션이 엔티티를 읽을 때, 현재의 버전 번호를 함께 읽는다.
      • 트랜잭션이 엔티티를 수정하고 저장하려고 할 때, 현재 데이터베이스에 저장된 버전 번호와 트랜잭션이 처음 읽어온 버전 번호를 비교한다.
    • 데이터 충돌 검출:
      • 트랜잭션이 데이터를 저장할 때, 데이터베이스에 저장된 버전 번호가 트랜잭션이 처음 읽어온 버전 번호와 동일하다면, 데이터가 수정되지 않았다고 간주하고 업데이트를 수행한다. 이때 버전 번호는 증가한다.
      • 반면, 버전 번호가 다르면, 다른 트랜잭션이 데이터를 수정한 것으로 간주하고, 현재 트랜잭션을 롤백하거나 재시도하도록 한다.

낙관적 락은 비관적 락에 비해 DB에서 락을 걸지 않기 때문에 성능이 향상되며, 병행 처리에 유리하다.
충돌 발생 시 트랜잭션을 롤백하거나 재시도 로직을 시도하는 등 유연성이 뛰어나다.
하지만 자주 변경되는 데이터의 경우 충돌이 자주 발생해 재시도 로직 호출이 너무 자주 발생할 수 있으며, 충돌을 처리하기 위한 로직을 따로 추가해야 하므로 복잡성이 증가한다.
따라서 충돌이 적고 병행 처리가 많은 시스템인지를 잘 고려해야 하고, 충돌 시 로직이 복잡할 수 있으므로 이를 잘 처리해야 한다.

profile
백엔드를 잘 하고 싶은 사람

0개의 댓글