[DDD] 낙관적 락의 경우 버저닝관련 문제점

문제 상황

@Entity
public class Order {
    @Id
    private Long id;
    @Version
    private Long version;
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<OrderLine> orderLines;

    // 기타 필드와 메서드
}

@Entity
public class OrderLine {
    @Id
    private Long id;
    private String product;
    private int quantity;
    @ManyToOne
    private Order order;

    // 기타 필드와 메서드
}
@Service
public class OrderService {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public void updateOrderLine(Long orderId, Long orderLineId, int newQuantity) {
        Order order = entityManager.find(Order.class, orderId); // 이전 버전 ..ex) 버전3
        OrderLine orderLine = findOrderLineInOrder(order, orderLineId); 
        if (orderLine != null) {
            orderLine.setQuantity(newQuantity);
            // Order 엔티티의 버전은 증가하지 않음
        }
    }

    private OrderLine findOrderLineInOrder(Order order, Long orderLineId) {
        for (OrderLine line : order.getOrderLines()) {
            if (line.getId().equals(orderLineId)) {
                return line;
            }
        }
        return null;
    }
}
  • updateOrderLine
    • 에서 주문 내의 특정 주문 라인의 수량을 변경하게 된다.
    • Order 엔티티 는 루트 애그리거트로서, 조회당시에는 이전 버전의 애그리거트로 조회된다.

      하지만, Order 내의 OrderLine 이 변경된 경우 낙관적 락의 경우 버전을 변경하지 않음.

비선점의 경우

  • 만약 내부의 속성이 변경되어 버전이 증가해야하는 경우,

LockModeType.OPTIMISTIC_FORCE_INCREMENT 설정이 필요하다.

@Transactional
public void updateOrderLineWithForceIncrement(Long orderId, Long orderLineId, int newQuantity) {
    Order order = entityManager.find(Order.class, orderId, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
    OrderLine orderLine = findOrderLineInOrder(order, orderLineId);
    if (orderLine != null) {
        orderLine.setQuantity(newQuantity);
        // OPTIMISTIC_FORCE_INCREMENT를 사용하여 Order 엔티티의 버전이 증가함
    }
}
  • 해당 속성으로 내부 엔티티가 변경시에도 루트 애그리거트의 버전이 증가하게됨.


Uploaded by N2T