문제 상황
@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