Skip to content

Commit 022d90f

Browse files
committed
faet: 이벤트 기반 주문 트랜잭션과 쿠폰 사용 처리 분리
1 parent 9309db8 commit 022d90f

3 files changed

Lines changed: 39 additions & 4 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.loopers.application.event.coupon;
2+
3+
import com.loopers.application.order.OrderCreatedEvent;
4+
import com.loopers.domain.coupon.Coupon;
5+
import com.loopers.domain.coupon.CouponRepository;
6+
import com.loopers.support.error.CoreException;
7+
import com.loopers.support.error.ErrorType;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.stereotype.Component;
10+
import org.springframework.transaction.annotation.Propagation;
11+
import org.springframework.transaction.annotation.Transactional;
12+
import org.springframework.transaction.event.TransactionPhase;
13+
import org.springframework.transaction.event.TransactionalEventListener;
14+
15+
@Component
16+
@RequiredArgsConstructor
17+
public class CouponEventHandler {
18+
private final CouponRepository couponRepository;
19+
20+
@Transactional(propagation = Propagation.REQUIRES_NEW)
21+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
22+
public void onOrderCreated(OrderCreatedEvent event) {
23+
Long couponId = event.couponId();
24+
Coupon coupon = couponRepository.findById(couponId).orElseThrow(
25+
() -> new CoreException(ErrorType.NOT_FOUND, "존재하지 않는 쿠폰입니다.")
26+
);
27+
28+
coupon.useCoupon();
29+
}
30+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.loopers.application.order;
2+
3+
public record OrderCreatedEvent(Long couponId) {
4+
}

apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.loopers.application.orderitem.OrderItemInfo;
44
import com.loopers.domain.coupon.Coupon;
55
import com.loopers.domain.coupon.CouponRepository;
6-
import com.loopers.domain.coupon.CouponType;
76
import com.loopers.domain.order.Order;
87
import com.loopers.domain.order.OrderRepository;
98
import com.loopers.domain.orderitem.OrderItem;
@@ -15,6 +14,7 @@
1514
import com.loopers.support.error.CoreException;
1615
import com.loopers.support.error.ErrorType;
1716
import lombok.RequiredArgsConstructor;
17+
import org.springframework.context.ApplicationEventPublisher;
1818
import org.springframework.stereotype.Component;
1919
import org.springframework.transaction.annotation.Transactional;
2020

@@ -29,6 +29,7 @@ public class OrderFacade {
2929
private final UserRepository userRepository;
3030
private final ProductRepository productRepository;
3131
private final CouponRepository couponRepository;
32+
private final ApplicationEventPublisher publisher;
3233

3334
@Transactional
3435
public OrderResultInfo createOrder(OrderV1Dto.OrderRequest request) {
@@ -55,7 +56,7 @@ public OrderResultInfo createOrder(OrderV1Dto.OrderRequest request) {
5556
);
5657

5758
if (product.getStock() < item.quantity()) {
58-
throw new CoreException(ErrorType.BAD_REQUEST, product.getName() + "상품의 재고가 부족합니다.");
59+
throw new CoreException(ErrorType.BAD_REQUEST, product.getName() + " 상품의 재고가 부족합니다.");
5960
}
6061

6162
product.decreaseStock(item.quantity());
@@ -85,10 +86,10 @@ public OrderResultInfo createOrder(OrderV1Dto.OrderRequest request) {
8586
totalPrice = totalPrice
8687
.multiply(BigDecimal.valueOf(100 - rate))
8788
.divide(BigDecimal.valueOf(100));
88-
89-
coupon.useCoupon();
9089
}
9190

91+
publisher.publishEvent(new OrderCreatedEvent(couponId));
92+
9293
Order order = request.toEntity(totalPrice);
9394
Order saved = orderRepository.save(order);
9495

0 commit comments

Comments
 (0)