[DDD]애그리거트와 트랜잭션

문제 상황

  • 상황
    • 한 주문 애그리거트에 대해 운영자가 배송 상태로 변경하려고 하는 동안
    • 사용자가 배송지 주소를 변경한다면 어떤 문제가 발생할까?

상황 설명

  • 운영자 스레드:
    1. 주문 애그리거트를 구함
    1. 배송 상태로 변경
    1. 트랜잭션 커밋
  • 고객 스레드:
    1. 주문 애그리거트를 구함
    1. 배송지 변경
    1. 트랜잭션 커밋

      충돌!

문제점

  • 운영자와 고객이 동시에 같은 주문 애그리거트를 수정할 때 발생한다.
  • 트랜잭션마다 리포지터리는 새로운 애그리거트 객체를 생성한다.
  • 운영자 스레드와 고객 스레드는 같은 주문 애그리거트를 나타내지만
    • 물리적으로 다른 객체를 사용한다.
      • 같은 Order라도 서로 다른 메모리주소를 가지며,
        • 속성도 다를 수 있음.
  • 운영자 스레드가 주문 애그리거트 객체를 배송 상태로 변경해도, 고객 스레드가 사용하는 객체에는 영향을 주지 않는다.
  • 고객 스레드는 주문 애그리거트 객체가 아직 배송 상태 전이 아니므로 배송지 정보를 변경할 수 있다.
    • 고객 스레드와 운영자 스레드는 각각 독립적인 상황이라는 것을 생각!
  • 두 스레드가 트랜잭션을 커밋하면 DB에 수정 내용이 반영되어 배송 상태와 배송지 정보가 모두 변경된다.
    • 결국 마지막 트랜잭션이 적용이 되지만,
      • 둘다 트랜잭션 상의 어떠한 에러도 발생하지 않게됨.
  • 이로 인해 애그리거트의 일관성이 깨질 수 있다.

해결 방안

  • 선점 잠금(Pessimistic Lock)
    • 운영자가 배송지 정보를 조회하고 상태를 변경하는 동안 고객이 애그리거트를 수정하지 못하게 막는 방법.

    비관적 락

  • 비선점 잠금(Optimistic Lock)
    • 운영자가 배송지 정보를 조회한 후
    • 고객이 정보를 변경하면
    • 운영자가 애그리거트를 다시 조회한 뒤
    • 수정하도록 하는 방법.

    낙관적 락 ( 버저닝 )


Uploaded by N2T