스프링

ConcurrentHashMap vs 레코드 락

inle 2024. 10. 11. 11:02

1. ConcurrentHashMap을 이용한 동시성 제어

ConcurrentHashMap은 자바의 동시성 제어를 지원하는 자료구조입니다. 내부적으로 세분화된 락을 이용해, 멀티스레드 환경에서 안전하게 데이터를 조작할 수 있도록 설계되었습니다.

장점:

  • 빠른 읽기/쓰기 성능: 데이터는 메모리 내에 저장되며, 메모리 기반 동작이므로 읽기/쓰기 성능이 매우 우수합니다.
  • 낮은 오버헤드: 데이터 접근 시 락을 세분화(바이 락 스트라이핑)하여, 많은 스레드가 동시에 작업을 해도 병목 현상이 상대적으로 적습니다.
  • 효율적인 멀티스레드 처리: 대규모 다중 스레드 환경에서 빠르게 데이터를 처리할 수 있으며, 주로 캐시나 일시적인 데이터 저장에 유용합니다.

단점:

  • 영구 저장에 부적합: 메모리 기반이기 때문에, 시스템이 종료되면 데이터가 휘발됩니다. 따라서, 영속적인 데이터 처리를 필요로 하는 경우 적합하지 않습니다.
  • DB와의 일관성 유지 어려움: ConcurrentHashMap 자체는 데이터베이스와 직접 연동되지 않으므로, DB와 동기화가 필요한 상황에서는 별도의 처리가 필요합니다.

사용 시기:

  • 메모리 내에서만 동작하는 동시성 제어가 필요한 경우.
  • 데이터베이스에 비해 가벼운 동시성 제어가 필요하고, 일시적인 캐싱이나 메모리에서 처리해야 할 데이터가 있을 때.

2. 엔티티 매니저(Entity Manager)와 레코드 락을 이용한 동시성 제어

데이터베이스에서 엔티티 매니저를 통해 **레코드 잠금(Locking)**을 사용하는 방식은, 트랜잭션에서 데이터를 일관성 있게 유지하고 동시성을 제어하는 방법입니다. 데이터베이스 레벨에서 데이터 충돌을 방지하고, 필요한 경우 비관적 락 또는 낙관적 락을 사용할 수 있습니다.

비관적 락(Pessimistic Locking):

  • 비관적 락은 데이터가 변경될 가능성이 높다고 예상되는 상황에서, 트랜잭션 내에서 다른 트랜잭션이 데이터에 접근하지 못하게 막습니다.
  • 락을 획득한 트랜잭션이 완료될 때까지 다른 트랜잭션은 해당 레코드를 수정할 수 없습니다.

낙관적 락(Optimistic Locking):

  • 낙관적 락은 데이터 충돌 가능성이 적다고 가정하고, 레코드에 락을 걸지 않고 트랜잭션을 진행합니다. 트랜잭션이 완료되기 전에 다른 트랜잭션에서 데이터를 변경하면 충돌이 발생하여 예외가 발생합니다.
  • 트랜잭션 완료 시점에서 버전 번호 등을 사용해 충돌을 감지합니다.

장점:

  • 데이터 일관성 보장: 데이터베이스 레벨에서 락을 걸어주므로, 동시성 문제에 대해 보다 강력한 제어가 가능합니다.
  • 영속성: 데이터가 메모리에만 있는 것이 아니라, 실제 데이터베이스에 기록되고 트랜잭션의 ACID 특성을 따르므로 시스템이 종료되더라도 데이터가 유지됩니다.
  • 낙관적 락의 효율성: 충돌 가능성이 적을 때는 낙관적 락을 사용해 성능 손실을 최소화할 수 있습니다.

단점:

  • 오버헤드: 데이터베이스 락은 ConcurrentHashMap에 비해 상대적으로 높은 오버헤드를 동반합니다. 특히 비관적 락은 트랜잭션이 길어질수록 성능 저하가 발생할 수 있습니다.
  • 동시성 처리 성능 저하: 다중 트랜잭션이 동일한 레코드를 수정하려고 할 경우, 대기 시간이 길어져 성능이 떨어질 수 있습니다.

사용 시기:

  • 데이터베이스에 영구적으로 저장되는 레코드의 동시성 제어가 필요한 경우.
  • 트랜잭션의 일관성을 보장해야 하는 상황에서 사용. 예를 들어, 다수의 사용자가 동시에 같은 제품에 리뷰를 남길 때.

어떤 방식이 더 효율적인가?

  • 메모리 기반 동시성 제어: 캐시나 일시적인 데이터 처리와 같은 메모리 내 작업에서 동시성을 제어하고자 한다면, ConcurrentHashMap이 더 효율적입니다. 성능이 매우 빠르며, 비교적 간단하게 구현할 수 있기 때문입니다.
  • 데이터베이스 기반 동시성 제어: DB에 저장된 레코드에 대한 동시성 제어가 필요하다면, 엔티티 매니저를 통한 레코드 락이 적합합니다. 비관적 또는 낙관적 락을 사용하여 트랜잭션 내에서 데이터 일관성을 보장할 수 있기 때문에, 데이터 무결성이 중요한 경우에 더 효율적입니다.

결론:

  • 빠른 메모리 기반 처리가 필요하고 데이터 일관성이 절대적으로 중요하지 않은 경우라면 ConcurrentHashMap이 적합합니다.
  • 데이터베이스에 영속적 데이터 저장 데이터 일관성 보장이 필요한 경우라면 엔티티 매니저의 락 메커니즘이 더 효율적입니다.

 

    1. 단순 조회 또는 단순 데이터 저장 작업:
      • ConcurrentHashMap을 이용한 캐싱 방식이 더 효율적입니다.
      • 주로 읽기 작업에서 빠른 성능이 필요하거나, 메모리에서 바로 데이터를 제공할 수 있을 때 적합합니다.
      • 데이터베이스와 직접 상호작용하지 않기 때문에, 읽기 성능 최적화가 가능합니다.
    2. 데이터 수정 작업 또는 데이터베이스 상태를 변경해야 하는 경우:
      • 엔티티 매니저를 통한 데이터베이스 직접 락(비관적 락 또는 낙관적 락) 방식이 더 적합합니다.
      • 데이터의 일관성무결성이 중요할 때, 여러 트랜잭션이 동시에 동일한 데이터를 수정하려고 할 때 충돌을 방지하기 위한 제어가 필요합니다.
      • 특히, 데이터베이스 트랜잭션에서 발생하는 동시성 문제를 해결하려면 비관적 락이나 낙관적 락을 사용하는 것이 더 안정적입니다.
    결론적으로:
    • 읽기 위주 또는 단순 삽입 작업에서는 ConcurrentHashMap을 사용하여 캐시 기반 성능 최적화를 추구하는 것이 좋습니다.
    • 수정 작업이나 데이터베이스 상태를 변경하는 트랜잭션에서는 엔티티 매니저의 락 메커니즘을 사용해 데이터 무결성을 보장하는 것이 적합합니다.

'스프링' 카테고리의 다른 글

ConcurrentHashMap  (1) 2024.10.11
MVP 단계 트러블 슈팅  (0) 2024.04.12
Mybatis와 JPA  (2) 2024.03.12
스프링컨테이너와 빈  (0) 2024.03.03
IoC & DI  (0) 2024.02.25