๐ 10.1. ์์คํ ๊ฐ ๊ฐ๊ฒฐํฉ ๋ฌธ์
์ผํ๋ชฐ์์ ๊ตฌ๋งค ํ ์ทจ์๋ฅผ ํ๋ฉด ํ๋ถ๋์ด์ผ ํ๋ ์ํฉ.
๋๋ฉ์ธ ๊ฐ์ฒด์ ์๋น์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ๋ ์ํฉ.
๋ณดํต ๊ฒฐ์ ์์คํ ์ด ์ธ๋ถ์ ์กด์ฌํ๋ฏ๋ก RefundService๋ ์ธ๋ถ์ ์๋ ๊ฒฐ์ ์์คํ ์ด ์ ๊ณตํ๋ ํ๋ถ ์๋น์ค๋ฅผ ํธ์ถํจ.
//๋๋ฉ์ธ ์๋น์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋ ๊ฒฝ์ฐ
public class Order{
public void cancel(RefundService refundService){
//์ฃผ๋ฌธ ๋ก์ง
verifyNotYetShipped();
this.state = OrderState.CANCELED;
//๊ฒฐ์ ๋ก์ง
this.refundStatus = State.REFUND_STARTED;
try{
refundService.refund(getPaymendId());
this.refundStatus = State.REFUND_COMPLETED;
} catch(Exception ex){
???
}
}
...
//์์ฉ ์๋น์ค์์ ํ๋ถ ๊ธฐ๋ฅ์ ์ํํ๋ ๊ฒฝ์ฐ
public class CancelOrderService{
private RefundService refundService;
@Transactional
public void cancel(OrderNo orderNo){
Order order = findOrder(orderNo);
order.cancel();
order.refundStarted();
try{
refundService.refund(order.getPaymentId());
order.refundCompleted();
} catch(Exception e){
???
}
}
...
๋ฌธ์ 1. ์ธ๋ถ ์๋น์ค๊ฐ ์ ์์ด ์๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ฒ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ํด์ผ ํ๋๊ฐ?
๋ฌธ์ 2. ์ธ๋ถ ์๋น์ค ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฐ๊ฒ ๋จ.
๋ฌธ์ 3. Order๋ ์ฃผ๋ฌธ์ ํํํ๋ ๊ฐ์ฒด์ธ๋ฐ ๊ฒฐ์ ๋๋ฉ์ธ์ ํ๋ถ ๊ด๋ จ ๋ก์ง๊ณผ ๋ค์์ด๊ฒ ๋จ. ํ๋ถ ๊ธฐ๋ฅ์ด ๋ฐ๋๋ฉด Order๋ ์ํฅ์ ๋ฐ์์ ์๋ฏธ -> ์ฃผ๋ฌธ ๋๋ฉ์ธ ๊ฐ์ฒด์ ์ฝ๋๋ฅผ ๊ฒฐ์ ๋๋ฉ์ธ ๋๋ฌธ์ ๋ณ๊ฒฝํ ์ง๋ ๋ชจ๋ฅด๋ ์ํฉ์ ์ข์ง ์์
๋ฌธ์ 4. ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ๋ก์ง์ด ์์ด๊ณ ํธ๋์ญ์ ์ฒ๋ฆฌ๊ฐ ๋ ๋ณต์กํด์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํจ.
์ด๋ฌํ ๋ฌธ์ ๋ค์ ์ฃผ๋ฌธ ๋ฐ์ด๋๋ ์ปจํ ์คํธ์ ๊ฒฐ์ ๋ฐ์ด๋๋ ์ปจํ ์คํธ ๊ฐ์ ๊ฐ๊ฒฐํฉ high coupling ๋๋ฌธ์ด๋ค.
์ฃผ๋ฌธ์ด ๊ฒฐ์ ์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์์ด ์ฃผ๋ฌธ ๋ฐ์ด๋๋ ์ปจํ ์คํธ๊ฐ ๊ฒฐ์ ๋ฐ์ด๋๋ ์ปจํ ์คํธ์ ์ํฅ์ ๋ฐ์.
์ด๋ฐ ๊ฐํ ๊ฒฐํฉ์ ์์ ๋ ๋ฐฉ๋ฒ: ์ด๋ฒคํธ.
ํนํ ๋น๋๊ธฐ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ์์คํ ๊ฐ์ ๊ฒฐํฉ์ ํฌ๊ฒ ๋ฎ์ถ ์ ์์.
๐ 10.2. ์ด๋ฒคํธ ๊ฐ์
์ด๋ฒคํธ: '๊ณผ๊ฑฐ์ ๋ฒ์ด์ง ์ด๋ค ๊ฒ'
10.2.1 ์ด๋ฒคํธ ๊ด๋ จ ๊ตฌ์ฑ ์์
๋๋ฉ์ธ ๋ชจ๋ธ์ ์ด๋ฒคํธ๋ฅผ ๋์ ํ๋ ค๋ฉด ์ด๋ฒคํธ์ ๊ตฌ์ฑ์์์ธ ์ด๋ฒคํธ, ์ด๋ฒคํธ ์์ฑ ์ฃผ์ฒด, ์ด๋ฒคํธ ๋์คํจ์ฒ(ํผ๋ธ๋ฆฌ์ ), ์ด๋ฒํธ ํธ๋ค๋ฌ(๊ตฌ๋ ์)๋ฅผ ๊ตฌํํด์ผ ํจ.
์ด๋ฒคํธ ์์ฑ ์ฃผ์ฒด: ์ํฐํฐ, ๋ฐธ๋ฅ, ๋๋ฉ์ธ ์๋น์ค์ ๊ฐ์ ๋๋ฉ์ธ ๊ฐ์ฒด. ๋๋ฉ์ธ ๊ฐ์ฒด๋ ๋๋ฉ์ธ ๋ก์ง์ ์คํํด์ ์ํ๊ฐ ๋ฐ๋๋ฉด ๊ด๋ จ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํด.
์ด๋ฒคํธ ํธ๋ค๋ฌ: ์ด๋ฒคํธ ์์ฑ ์ฃผ์ฒด๊ฐ ๋ฐ์ํ ์ด๋ฒคํธ์ ๋ฐ์. ์๋ฅผ ๋ค์ด '์ฃผ๋ฌธ ์ทจ์๋จ ์ด๋ฒคํธ'๋ฅผ ๋ฐ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํด๋น ์ฃผ๋ฌธ์ ์ฃผ๋ง์์๊ฒ SMS๋ก ์ฃผ๋ฌธ ์ทจ์ ์ฌ์ค์ ํต์ง.
์ด๋ฒคํธ ๋์คํจ์ฒ: ์ด๋ฒคํธ ์์ฑ ์ฃผ์ฒด์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํด ์ฃผ๋ ๊ฒ.
10.2.2 ์ด๋ฒคํธ์ ๊ตฌ์ฑ
์) ๋ฐฐ์ก์ง ๋ณ๊ฒฝํ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ
์ด๋ฒคํธ๋ฅผ ์ํ ํด๋์ค. ์ด๋ฒคํธ๋ ํ์ฌ ๊ธฐ์ค์ผ๋ก ๊ณผ๊ฑฐ์ ๋ฒ์ด์ง ๊ฒ์ด๋ฏ๋ก ์ด๋ฆ์ ๊ณผ๊ฑฐ ์์ ์ฌ์ฉํจ.
public class ShippingInfoChangedEvnet{
private String orderNumber;
private long timestamp;
private ShippingInfo newShippingInfo;
//์์ฑ์, getter
}
์ด๋ฒคํธ๋ฅผ ๋ฐ์ํ๋ ์ฃผ์ฒด๋ Order ์ ๊ทธ๋ฆฌ๊ฑฐํธ.
public class Order {
public void changeShippingInfo(ShippingInfo newShippingInfo){
verifyNotYerShipped();
setShippingInfo(newShippingInfo);
Events.raise(new ShippingInfoChangedEvent(number, newShippingInfo));
}
...
}
10.2.3 ์ด๋ฒคํธ ์ฉ๋
์ฒซ ๋ฒ์งธ: ํธ๋ฆฌ๊ฑฐ. ๋๋ฉ์ธ์ ์ํ๊ฐ ๋ฐ๋ ๋ ๋ค๋ฅธ ํ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ฉด ํ์ฒ๋ฆฌ๋ฅผ ์คํํ๊ธฐ ์ํ ํธ๋ฆฌ๊ฑฐ๋ก ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ ์ ์์.
๋ ๋ฒ์งธ: ์๋ก ๋ค๋ฅธ ์์คํ ๊ฐ์ ๋ฐ์ดํฐ ๋๊ธฐํ. ex) ๋ฐฐ์ก์ง๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์ธ๋ถ ๋ฐฐ์ก ์๋น์ค์ ๋ฐ๋ ๋ฐฐ์ก์ง ์ ๋ณด๋ฅผ ์ ์กํด์ผ ํจ.
10.2.4 ์ด๋ฒคํธ ์ฅ์
์๋ก ๋ค๋ฅธ ๋๋ฉ์ธ ๋ก์ง์ด ์์ด๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์.
๐ 10.3 ์ด๋ฒคํธ, ํธ๋ค๋ฌ, ๋์คํจ์ฒ ๊ตฌํ
10.3.1 ์ด๋ฒคํธ ํด๋์ค
์ด๋ฒคํธ ์์ฒด๋ฅผ ์ํ ์์ ํ์ ์ ์กด์ฌํ์ง ์๊ณ ์ํ๋ ํด๋์ค๋ฅผ ์ด๋ฒคํธ๋ก ์ฌ์ฉํ๋ฉด ๋จ. ์ด๋ฆ์ ๊ณผ๊ฑฐ ์์ ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ ์ ๋ง ์ ์.
์ด๋ฒคํธ ํด๋์ค๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋๋ฐ ํ์ํ ์ต์ํ์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํด์ผ ํจ.
10.3.2 Events ํด๋์ค์ ApplicationEventPublisher
์ด๋ฒคํธ ๋ฐ์๊ณผ ์ถํ์ ์ํด ์คํ๋ง์ด ์ ๊ณตํ๋ ApplicationEventPublisher๋ฅผ ์ฌ์ฉํจ.
import org.springframework.context.ApplicationEventPublisher;
public class Events {
private static ApplicationEventPublisher publisher;
static void setPublisher(ApplicationEventPublisher publisher) {
Events.publisher = publisher;
}
public static void raise(Object event){
if(publisher != null){
publisher.publishEvent(event);
}
}
}
10.3.3 ์ด๋ฒคํธ ๋ฐ์๊ณผ ์ด๋ฒคํธ ํธ๋ค๋ฌ
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์คํ๋ง์ด ์ ๊ณตํ๋ @EventListener ์ ๋ํ ์ด์ ์ผ๋ก ๊ตฌํํจ.
@Service
public class OrderCanceledEventHandler {
private RefundService refundService;
public OrderCanceledEventHandler(RefundService refundService) {
this.refundService = refundService;
}
@EventListener(OrderCanceledEvent.class)
public void handle(OrderCanceledEvent event){
refundService.refund(event.getOrderNumber());
}
}
10.3.4 ํ๋ฆ ์ ๋ฆฌ
1. ๋๋ฉ์ธ ๊ธฐ๋ฅ ์คํ.
2. ๋๋ฉ์ธ ๊ธฐ๋ฅ์ Events.raise()๋ฅผ ์ด์ฉํด ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํด.
3. Events.rais()๋ ์คํ๋ง์ด ์ ๊ณตํ๋ ApplicationEventPublisher๋ฅผ ์ด์ฉํด ์ด๋ฒคํธ ์ถํ.
4. ApplicationEventPublisher๋ @EventListener(์ด๋ฒคํธํ์ .class) ์ ๋ํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ฅผ ์ฐพ์ ์คํํ๋ค.
๐ 10.4. ๋๊ธฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฌธ์
์ด๋ฒคํธ ์ฌ์ฉํด์ ๊ฐ๊ฒฐํฉ ๋ฌธ์ ํด์ํจ. ์ธ๋ถ ์๋น์ค์ ์ํฅ์ ๋ฐ๋ ๋ฌธ์ ๊ฐ ๋จ์ ์์.
//1. ์์ฉ ์๋น์ค ์ฝ๋
@Transactional
public void cancel(OrderNo orderNo) {
Order order = findOrder(orderNo);
order.cancel(); //order.cancle()์์ OrderCanceledEvent ๋ฐ์
}
//2. ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋
@Service
public class OrderCanceledEventHandler {
...์๋ต
@EventListener(OrderCanceledEvent.class)
public void handle(OrderCanceledEvent event) {
//์ธ๋ถ ํ๋ถ ์๋น์ค์ ์ฐ๊ฒฐ๋
//refundService.refund()๊ฐ ๋๋ ค์ง๊ฑฐ๋ ์ต์
์
์ด ๋ฐ์ํ๋ฉด?
refundService.refund(event.getOrderNumber());
}
}
์์คํ ์ฑ๋ฅ ์ ํ ๋ฟ๋ง ์๋๋ผ ํธ๋์ญ์ ๋ ๋ฌธ์ .
ํธ๋์ญ์ ์ ๋กค๋ฐฑ ํด์ผ ํ ๊น? ํธ๋์ญ์ ์ ๋กค๋ฐฑ ํ๋ฉด ๋ฃจ๋งค ์ทจ์ ๊ธฐ๋ฅ์ ๋กค๋ฐฑ ํ๋ ๊ฒ์ด๋ฏ๋ก ๊ตฌ๋งค ์ทจ์๊ฐ ์คํจํ๋ ๊ฒ๊ณผ ๊ฐ์.
์ธ๋ถ ์์คํ ๊ณผ์ ์ฐ๋์ ๋๊ธฐ๋ก ์ฒ๋ฆฌํ ๋ ๋ฐ์ํ๋ ์ฑ๋ฅ๊ณผ ํธ๋์ญ์ ๋ฒ์ ๋ฌธ์ ๋ฅผ ํด์ํ๋ ๋ฐฉ๋ฒ์
1. ์ด๋ฒคํธ๋ฅผ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๊ฑฐ๋
2. ์ด๋ฒคํธ์ ํธ๋์ญ์ ์ ์ฐ๊ณํ๋ ๊ฒ.
๐ 10.5. ๋น๋๊ธฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ
'Aํ๋ฉด ์ด์ด์ Bํ๋ผ'๋ ๋ด์ฉ์ ๋ด๊ณ ์๋ ์๊ตฌ์ฌํญ์ ์ค์ ๋ก 'A ํ๋ฉด ์ต๋ ์ธ์ ๊น์ง B ํ๋ผ'์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์.
ex) ์ด๋ฉ์ผ ์ธ์ฆ, ์ฃผ๋ฌธ ์ทจ์ ํ ๊ฒฐ์ ์ทจ์ ๋ฑ
์๊ตฌ์ฌํญ์ ์ด๋ฒคํธ๋ฅผ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์. ์ฆ A ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ณ๋ ์ค๋ ๋๋ก B๋ฅผ ์ํํ๋ ํธ๋ค๋ฌ๋ฅผ ์คํํ๋ ๋ฐฉ์์ผ๋ก ์๊ตฌ์ฌํญ์ ๊ตฌํ.
๋ค์ํ ์ด๋ฒคํธ ๋น๋๊ธฐ ๊ตฌํ ๋ฐฉ๋ฒ ์ค ๋ค์ ๋ค ๊ฐ์ง๋ฅผ ์์๋ด.
1. ๋ก์ปฌ ํธ๋ค๋ฌ๋ฅผ ๋น๋๊ธฐ๋ก ์คํํ๊ธฐ
2. ๋ฉ์์ง ํ๋ฅผ ์ฌ์ฉํ๊ธฐ
3. ์ด๋ฒคํธ ์ ์ฅ์์ ์ด๋ฒคํธ ํฌ์๋ ์ฌ์ฉํ๊ธฐ
4. ์ด๋ฒคํธ ์ ์ฅ์์ ์ด๋ฒคํธ ์ ๊ณต API ์ฌ์ฉํ๊ธฐ
10.5.1 ๋ก์ปฌ ํธ๋ค๋ฌ ๋น๋๊ธฐ ์คํ
์คํ๋ง์ @Async ์ ๋ํ ์ด์ ์ผ๋ก ์์ฝ๊ฒ ๋น๋๊ธฐ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ ์คํํ ์ ์๋ค.
- @EnabledAsync ์ ๋ํ ์ด์ ์ ์ฌ์ฉํด์ ๋น๋๊ธฐ ๊ธฐ๋ฅ์ ํ์ฑํํ๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฉ์๋์ @Async ์ ๋ํ ์ด์ ์ ๋ถ์ธ๋ค.
10.5.2 ๋ฉ์์ง ์์คํ ์ ์ด์ฉํ ๋น๋๊ธฐ ๊ตฌํ
์นดํ์นด๋ ๋๋นMQ์ ๊ฐ์ ๋ฉ์์ง ์์คํ ์ ์ฌ์ฉํ๋ ๊ฒ.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ๋์คํจ์ฒ๋ ์ด๋ฒคํธ๋ฅผ ๋ฉ์์ง ํ์ ๋ณด๋.
๋ฉ์์ง ํ๋ ์ด๋ฒคํธ๋ฅผ ๋ฉ์์ง ๋ฆฌ์ค๋์ ์ ๋ฌํ๊ณ , ๋ฉ์์ง ๋ฆฌ์ค๋๋ ์๋ง์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ด์ฉํด ์ด๋ฒคํธ ์ฒ๋ฆฌ.
์ด๋ฒคํธ๋ฅผ ๋ฉ์์ง ํ์ ์ ์ฅํ๋ ๊ณผ์ ๊ณผ ๋ฉ์์ง ํ์์ ์ด๋ฒคํธ๋ฅผ ์ฝ์ด์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ ๋ณ๋ ์ค๋ ๋๋ ํ๋ก์ธ์ค๋ก ์ฒ๋ฆฌ๋จ.
10.5.3 ์ด๋ฒคํธ ์ ์ฅ์๋ฅผ ์ด์ฉํ ๋น๋๊ธฐ ์ฒ๋ฆฌ
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํธ๋ค๋ฌ๋ ์คํ ๋ฆฌ์ง์ ์ด๋ฒคํธ๋ฅผ ์ ์ฅํจ.
ํฌ์๋๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์ด๋ฒคํธ ์ ์ฅ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์ ธ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์คํํจ.
ํฌ์๋๋ ๋ณ๋ ์ค๋ ๋๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ๋ฐํ๊ณผ ์ฒ๋ฆฌ๊ฐ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ๋จ.
ํฌ์๋ ๋ฐฉ์์ด ํฌ์๋๋ฅผ ์ด์ฉํด์ ์ด๋ฒคํธ๋ฅผ ์ธ๋ถ์ ์ ๋ฌํ๋ค๋ฉด, API ๋ฐฉ์์ ์ธ๋ถ ํธ๋ค๋ฌ๊ฐ API ์๋ฒ๋ฅผ ํตํด ์ด๋ฒคํธ ๋ชฉ๋ก์ ๊ฐ์ ธ๊ฐ. API ๋ฐฉ์์์๋ ์ด๋ฒคํธ ๋ชฉ๋ก์ ์๊ตฌํ๋ ์ธ๋ถ ํธ๋ค๋ฌ๊ฐ ์์ ์ด ์ด๋๊น์ง ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋์ง ๊ธฐ์ตํด์ผ ํจ.
์ด๋ฒคํธ ์ ์ฅ์ ๊ตฌํ
- EventEntry: ์ด๋ฒคํธ ์ ์ฅ์์ ๋ณด๊ดํ ๋ฐ์ดํฐ. EventEntry๋ ์ด๋ฒคํธ๋ฅผ ์๋ณํ๊ธฐ ์ํ id, ์ด๋ฒคํธ ํ์ ์ธ type, ์ง๋ ฌํํ ๋ฐ์ดํฐ ํ์์ธ contentType, ์ด๋ฒคํธ ๋ฐ์ดํฐ ์์ฒด์ธ payload, ์ด๋ฒคํธ ์๊ฐ์ธ timestamp๋ฅผ ๊ฐ๋๋ค.
- EventStore: ์ด๋ฒคํธ๋ฅผ ์ ์ฅํ๊ณ ์กฐํํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณต
- JdbcEventStore: JDBC๋ฅผ ์ด์ฉํ EventStore ๊ตฌํ ํด๋์ค.
- EventApi: REST API๋ฅผ ์ด์ฉํด์ ์ด๋ฒคํธ ๋ชฉ๋ก์ ์ ๊ณตํ๋ ์ปจํธ๋กค๋ฌ.
REST API ๊ตฌํ
offset๊ณผ limit ํ๋ผ๋ฏธํฐ๋ฅผ ์ด์ฉํ๋ REST API๋ฅผ ์คํ๋ง MVC ์ปจํธ๋กค๋ฌ๋ฅผ ์ด์ฉํด ๊ตฌํํจ.
ํฌ์๋ ๊ตฌํ
์คํ๋ง์ @Scheduled ์ ๋ํ ์ด์ ํน์ ๋ณ๋ ์ค์ผ์ค๋ง ํ๋ ์์ํฌ๋ฅผ ์ด์ฉํด ๋ฉ์๋๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์คํ.
๐ 10.6. ์ด๋ฒคํธ ์ ์ฉ ์ ์ถ๊ฐ ๊ณ ๋ ค ์ฌํญ
1. ์ด๋ฒคํธ ์์ค๋ฅผ EventEntry์ ์ถ๊ฐํ ์ง ์ฌ๋ถ
2. ํฌ์๋์์ ์ ์ก ์คํจ๋ฅผ ์ผ๋ง๋ ํ์ฉํ ๊ฒ์ด๋์ ๋ํ ๊ฒ
3. ์ด๋ฒคํธ ์์ค์ ๋ํ ๊ฒ
4. ์ด๋ฒคํธ ์์
5. ์ด๋ฒคํธ ์ฌ์ฒ๋ฆฌ
10.6.1 ์ด๋ฒคํธ ์ฒ๋ฆฌ์ DB ํธ๋์ญ์ ๊ณ ๋ ค
์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ๋๊ธฐ๋ฅผ ํ๋ ๋น๋๊ธฐ๋ก ํ๋ ์ด๋ฒคํธ ์ฒ๋ฆฌ ์คํจ์ ํธ๋์ญ์ ์คํจ๋ฅผ ํจ๊ป ๊ณ ๋ คํด์ผ ํจ. ํธ๋์ญ์ ์ด ์ฑ๊ณตํ ๋๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์คํํ๋ฉด ๊ณ ๋ คํด์ผ ํ ์ฌํญ์ด ๋ ๋ณต์กํด์ง๋ค.
์คํ๋ง์ @TransactionalEventListener ์ ๋ํ ์ด์ ์ ์คํ๋ง ํธ๋์ญ์ ์ํ์ ๋ฐ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์คํํ ์ ์๊ฒ ํจ.