Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
DDD Start 부록
"수다"
신림프로그래머, 최범균, 2016-07-16
madvirus@madvirus.net
A/S 안내
• 책의 오류/오타 안내
– 다음 javacan 카페 à DDD Start QA 게시판
• http://cafe.daum.net/javacan/Qv4t/1
2
3
#1 수다
Bounded Context + Microservice
기능 측면에서 단일 시스템의 성장
4
단일코드
통합DB
거대한 강결합
5
서비스 레이어
Data 레이어
프리젠테이션
레이어
도메인 측면에서 문제
6
서비스 레이어
Data 레이어
프리젠테이션
레이어
통합DB:
언어 경계 없음
수직적으로
언어 경계 없음
컨텍스트 안에서만
존재하는 의미가
사라짐
잘 나눈 패키지로 문제 완화
7
user project …
여전히 경계가 모호해질 가능성
8
user project
User Project
USER PROJECTUSER_PROJ
* *
BC별 프로젝트로 분리
9
user
User
project
ProjectMemberService Adapter * 1
USER PROJECTMEMBER
분리에 따른 몇 가지 이점
• 명시적인 (강제) 언어 경계 à bounded
• 컨텍스트별 독립적인 발전
• 인터페이스에 기반한 컨텍스트 간 통신
10
Microservice의 특성
• James Lewis, Martin Fowler에 따르면
– 서비스로서 컴포넌트화
– 비지니스 수행에 따른 구성
– 프로젝트가 아닌 제품
– 똑똑한 엔드포인트와 더미(Dumb) 파이프
...
서비스로서 컴포넌트화
• 독립 배포 à 서비스의 응집도(경계) 높아짐
• 명시적 인터페이스 à 공개 인터페이스
12
비지니스 수행에 따른 구성
13
발췌: http://martinfowler.com/articles/microservices.html
분산화된 데이터 관리
14
발췌: http://martinfowler.com/articles/microservices.html
진화하는 설계
• 서비스별 독립적인 변경(교체/업그레이드)
15
MS à BC
16
언어의 경계를 찾아
Bounded Context를
구성하는데
도움을 줌
서비스로서 컴포넌트화
비지니스 수행에 따른 구성
분산화된 데이터 관리
진화하는 설계
고민거리
• MS로의 전환?
– 참가자 소환
17
18
수다 정리
19
#2 수다
Event Sourcing + Aggregate
주문의 변경 내역
20
state: PAYMENT_WAITING
lines: [ {prod:P001, price:1000,
quantity:1, amounts: 1000} ]
shippingInfo: {receiver:...
상태 변화 증분 = 이벤트
21
주문함
lines: {prod:P001, price:1000,
quantity:1, amounts: 1000}
shippingInfo: {receiver: 'bk', address: ad...
증분 누적 à 마지막 상태
22
주문함
lines: {prod:P001, price:1000,
quantity:1, amounts: 1000}
shippingInfo: {receiver: 'bk', address: ad...
이벤트 소싱Event Sourcing
23
* http://martinfowler.com/eaaDev/EventSourcing.html
어플리케이션의 모든 상태 변화를
순서에 따라 이벤트로 보관한다.
Capture al...
도메인 객체와 이벤트 소싱
• 도메인 객체 조회
– 저장한 이벤트로부터 도메인 객체 생성
• 도메인 객체 변경
– 모든 상태 변화에 대한 이벤트를 저장
• 일관성의 기준인 애그리거트Aggregate 단위
24
이벤트 구성
• 구성
– 애그리거트 타입
– 애그리거트 식별자
– 버전
– 이벤트 타입
– 이벤트 시간
– 증분(변경) 내역(payload)
• 이벤트 구분(unique idx)
– 애그리거트 타입, 애그리거트 식별자,...
애그리거트 조회
• 리포지토리
26
public	class	OrderRepository	{
public	Order	findById(String	orderId)	{
List<Event>	events	=	eventStore...
애그리거트 조회
• 애그리거트는 이벤트 반영
27
public	class	Order	extends	Aggregate	{				
public	void	on(OrderPlacedEvent	evt)	{
this.lines	=...
애그리거트 변경
• 애그리거트에서 이벤트 발생
28
public	class	Order	extends	Aggregate	{
public	void	cancel()	{
….
OrderCanceledEvent	evt	=	
ne...
애그리거트 변경
• 트랜잭션에서 이벤트 저장
29
public	class	CancelOrderService	{
@Transactional
public	void	cancel(String	orderId)	{
Order	or...
애그리거트 생성
• 애그리거트 생성자 : 생성 이벤트 발생
30
public	class	PlaceOrderService	{
@Transactional
public	void	cancel(String	orderId)	{
O...
이벤트 소싱과 유지보수
• 새로운 데이터 추가
31
public	class	Order	extends	Aggregate	{
private	String	note;
public	Order(…)	{
….
OrderCreated...
이벤트 소싱 적용한 애그리거트
• 임피던스 미스매치(impedance mismatch) 없음
• 애그리거트 간 참조는 ID
• 비선점 잠금
32
성능
• 단일 애그리것트 조회 à 스냅샷
• 복합 조회 à CQRS
33
SQL(ORM) vs 이벤트 소싱
• 변화되는 것
34
영역 적용 전 (RDBMS/ORM) 적용 후
도메인 객체 로딩 SQL : SELECT 쿼리
ORM : 프레임워크가 매핑
설정을 이용해서 SELECT 쿼리
실행
- ...
장점
• DB에 의존적이지 않은 도메인 코드 구현
– 테이블이나 ORM 기술의 제한/제약에서 벗어남
• 기능 변경
– 하위 호환 처리가 상대적으로 쉬움
– 이벤트로부터 완전히 새로운 도메인 객체의 생성도 가능
• 버그 ...
단점
• 익숙하지 않음
– SQL 위주(데이터 중심) 개발 성향인 경우 적응 힘듬
• 단순 모델에는 적합하지 않음
– 단순 모델에 적용하기엔 구현이 복잡해짐
• 도구 부족
– 이벤트 소싱과 CQRS 지원 프레임워크 부족...
37
두 번째 수다 정리
38
세 번째 수다
SAGA
길게 실행되는 프로세스
Long Running Business Process
39
주문하기 상품보내기 배송시작알리기
구매확정
요청하기
길게 실행되는 프로세스
40
주문하기 상품보내기
배송시작
알리기
구매확정
요청하기
배송시작함주문함
배송시작집하하기 전달
배송완료함
입금하기
결제함
길게 실행되는 프로세스/트랜잭션의 특징
• 여러 개의 작은 프로세스(트랜잭션)로 구성
• 하위 프로세스가 순서대로 실행되는 건 아님
• 여러 모듈/서비스가 (비동기로) 엮임
• 한 트랜잭션이 아님
• 실패는 롤백 대신 ...
SAGA
• 여러 하위 트랜잭션 집합으로 구성된 LLT
– LLT: Long Lived Transaction
– 단일 실행 단위
• 각 하위 트랜잭션은 단독 트랜잭션
– 하위 트랜잭션 단위로 일관성 보장
• 각 하위 트...
43
SAGA	à 프로세스 매니저
프로세스 매니저
• 여러 애그리거트/외부 시스템이 엮이는 긴
프로세스의 흐름 제어
– 각 구성 요소 간의 메시지 라우팅이 주된 역할
• 프로세스의 상태 보관
• 비즈니스 로직은 개별 구성 요소에서 처리
44
Saga / 프로세스 매니저
45
주문
프로세스 매니저
배송 서비스
결제 서비스
주문
애그리거트
재고
애그리거트
Paid
Event
배송지시
OrderCreated
Event
Delivery
Completed
Event...
구현
• 특정 이벤트에 Saga/프로세스 매니저 시작
• 수신한 이벤트에 따라 다음 기능 실행
– 실패시, 후속 보상 기능 실행
• 전체 프로세스가 끝나면 Saga/프로세스
매니저 종료
46
상태 존재 à 프로세스별 인스턴스
• 에어카텔 상품 구매 예
47
public	class	BookingProcessManager	{
private	BookingId	bookingId;
private	BookingStat...
실패 보상 처리
• 에어카텔 호텔 예약 실패 예
48
public	class	BookingProcessManager	{
public	void	handle(HotelBookingFailedEvent	evt)	{
cance...
필요한 것
• SAGA/매니저 상태 영속화
– 상태가 유실되지 않아야 함
• 이벤트 à 해당 SAGA/매니저
– 효과적인 SAGA 검색 수단 필요
• SAGA 타임아웃
49
특징
• 개별 애그리거트는 자기 자신의 도메인
로직에만 집중하면 됨
• 한 비즈니스 프로세스와 관련된 흐름 제어가
한 곳에 모임
– 프로세스 변경 용이
• (주로) 비동기 이벤트 기반
• SAGA/프로세스 매니저 인스턴...
51
세 번째 수다 정리
52
마무리
Upcoming SlideShare
Loading in …5
×

Ddd start 부록 지앤선&ksug

8,636 views

Published on

DDD Start 부록 "수다"

Published in: Technology
  • DOWNLOAD THAT BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download Full doc Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book that can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer that is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story That Helped Ignite a Movement,-- Atomic Habits: An Easy &amp; Proven Way to Build Good Habits &amp; Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money That the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths that Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 강의영상: https://www.youtube.com/playlist?list=PLn0dGEB80JNQ5FXJDQ_HPi18rOQaHJee_
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Ddd start 부록 지앤선&ksug

  1. 1. DDD Start 부록 "수다" 신림프로그래머, 최범균, 2016-07-16 madvirus@madvirus.net
  2. 2. A/S 안내 • 책의 오류/오타 안내 – 다음 javacan 카페 à DDD Start QA 게시판 • http://cafe.daum.net/javacan/Qv4t/1 2
  3. 3. 3 #1 수다 Bounded Context + Microservice
  4. 4. 기능 측면에서 단일 시스템의 성장 4 단일코드 통합DB
  5. 5. 거대한 강결합 5 서비스 레이어 Data 레이어 프리젠테이션 레이어
  6. 6. 도메인 측면에서 문제 6 서비스 레이어 Data 레이어 프리젠테이션 레이어 통합DB: 언어 경계 없음 수직적으로 언어 경계 없음 컨텍스트 안에서만 존재하는 의미가 사라짐
  7. 7. 잘 나눈 패키지로 문제 완화 7 user project …
  8. 8. 여전히 경계가 모호해질 가능성 8 user project User Project USER PROJECTUSER_PROJ * *
  9. 9. BC별 프로젝트로 분리 9 user User project ProjectMemberService Adapter * 1 USER PROJECTMEMBER
  10. 10. 분리에 따른 몇 가지 이점 • 명시적인 (강제) 언어 경계 à bounded • 컨텍스트별 독립적인 발전 • 인터페이스에 기반한 컨텍스트 간 통신 10
  11. 11. Microservice의 특성 • James Lewis, Martin Fowler에 따르면 – 서비스로서 컴포넌트화 – 비지니스 수행에 따른 구성 – 프로젝트가 아닌 제품 – 똑똑한 엔드포인트와 더미(Dumb) 파이프 – 분산화 거버넌스 – 분산화된 데이터 관리 – 인프라 자동화 – 장애 방지 설계 – 진화하는 설계 11 * http://martinfowler.com/articles/microservices.html
  12. 12. 서비스로서 컴포넌트화 • 독립 배포 à 서비스의 응집도(경계) 높아짐 • 명시적 인터페이스 à 공개 인터페이스 12
  13. 13. 비지니스 수행에 따른 구성 13 발췌: http://martinfowler.com/articles/microservices.html
  14. 14. 분산화된 데이터 관리 14 발췌: http://martinfowler.com/articles/microservices.html
  15. 15. 진화하는 설계 • 서비스별 독립적인 변경(교체/업그레이드) 15
  16. 16. MS à BC 16 언어의 경계를 찾아 Bounded Context를 구성하는데 도움을 줌 서비스로서 컴포넌트화 비지니스 수행에 따른 구성 분산화된 데이터 관리 진화하는 설계
  17. 17. 고민거리 • MS로의 전환? – 참가자 소환 17
  18. 18. 18 수다 정리
  19. 19. 19 #2 수다 Event Sourcing + Aggregate
  20. 20. 주문의 변경 내역 20 state: PAYMENT_WAITING lines: [ {prod:P001, price:1000, quantity:1, amounts: 1000} ] shippingInfo: {receiver: 'bk', address: addr} 주문함 lines: {prod:P001, price:1000, quantity:1, amounts: 1000} shippingInfo: {receiver: 'bk', address: addr} 결제함 state: PREPARING lines: [ {prod:P001, price:1000, quantity:1, amounts: 1000} ] shippingInfo: {receiver: 'bk', address: addr} 배송지변경함 shippingInfo: {receiver: 'es', address: addr2} state: PREPARING lines: [ {prod:P001, price:1000, quantity:1, amounts: 1000} ] shippingInfo: {receiver: 'es', address: addr2} 발송함 state: SHIPPED lines: [ {prod:P001, price:1000, quantity:1, amounts: 1000} ] shippingInfo: {receiver: 'es', address: addr2}
  21. 21. 상태 변화 증분 = 이벤트 21 주문함 lines: {prod:P001, price:1000, quantity:1, amounts: 1000} shippingInfo: {receiver: 'bk', address: addr} 결제함 배송지변경함 shippingInfo: {receiver: 'es', address: addr2} 발송함
  22. 22. 증분 누적 à 마지막 상태 22 주문함 lines: {prod:P001, price:1000, quantity:1, amounts: 1000} shippingInfo: {receiver: 'bk', address: addr} 결제함 배송지변경함 shippingInfo: {receiver: 'es', address: addr2} 발송함 state: SHIPPED lines: [ {prod:P001, price:1000, quantity:1, amounts: 1000} ] shippingInfo: {receiver: 'es', address: addr2}
  23. 23. 이벤트 소싱Event Sourcing 23 * http://martinfowler.com/eaaDev/EventSourcing.html 어플리케이션의 모든 상태 변화를 순서에 따라 이벤트로 보관한다. Capture all changes to an application state as a sequence of events.
  24. 24. 도메인 객체와 이벤트 소싱 • 도메인 객체 조회 – 저장한 이벤트로부터 도메인 객체 생성 • 도메인 객체 변경 – 모든 상태 변화에 대한 이벤트를 저장 • 일관성의 기준인 애그리거트Aggregate 단위 24
  25. 25. 이벤트 구성 • 구성 – 애그리거트 타입 – 애그리거트 식별자 – 버전 – 이벤트 타입 – 이벤트 시간 – 증분(변경) 내역(payload) • 이벤트 구분(unique idx) – 애그리거트 타입, 애그리거트 식별자, 버전 25
  26. 26. 애그리거트 조회 • 리포지토리 26 public class OrderRepository { public Order findById(String orderId) { List<Event> events = eventStore.select(Order.class, orderId); if (events.isEmpty()) { return null; } Order order = new Order(); for (Event evt : events) { order.handle(evt); } addUOW(order); return order; }
  27. 27. 애그리거트 조회 • 애그리거트는 이벤트 반영 27 public class Order extends Aggregate { public void on(OrderPlacedEvent evt) { this.lines = evt.getOrderLines(); this.shippingInfo = evt.getShippingInfo(); } public void on(ShippingInfoChangedEventevt) { this.shippingInfo = evt.getShippingInfo(); } public void on(ShippedEvent evt) { this.state = SHIPPED; } public abstract class Aggregate { private Integer version; public void handle(Event evt) { this.version = evt.getVersion(); Events.handle(this, evt); } }
  28. 28. 애그리거트 변경 • 애그리거트에서 이벤트 발생 28 public class Order extends Aggregate { public void cancel() { …. OrderCanceledEvent evt = new OrderCanceledEvent(getId(), version + 1); super.apply(evt); } public abstract class Aggregate { List<Event> uncommittedEvents; public void apply(Event evt) { addUncommittedEvent(evt); handle(evt); } public List<Event> getUncommittedEvents() { return uncommittedEvents; }
  29. 29. 애그리거트 변경 • 트랜잭션에서 이벤트 저장 29 public class CancelOrderService { @Transactional public void cancel(String orderId) { Order order = orderRepository.findById(orderId); checkNull(order); order.cancel(); } } class TransactionHandler { public void commit() { List<Aggregate> aggs = getAllUOW(); for (Aggregate agg : aggs) { eventStore.append( agg.getClass(), agg.getUncomittedEvents() ); } }
  30. 30. 애그리거트 생성 • 애그리거트 생성자 : 생성 이벤트 발생 30 public class PlaceOrderService { @Transactional public void cancel(String orderId) { Order order = new Order(…); repository.save(order); } } public class Order extends Aggregate { public Order(…) { …. OrderCreatedEvent evt = new OrderCreatedEvent( getId(), lines, shippingInfo, 1); super.apply(evt); }
  31. 31. 이벤트 소싱과 유지보수 • 새로운 데이터 추가 31 public class Order extends Aggregate { private String note; public Order(…) { …. OrderCreatedV2Event evt = new OrderCreatedV2Event(...); super.apply(evt); } public void on(OrderCreatedEvent evt) { … this.note = ""; } public void on(OrderCreatedV2Event evt) { … this.note = evt.getNote(); } 없어지는 것 - DB 작업 일정 - 매핑 설정 변경
  32. 32. 이벤트 소싱 적용한 애그리거트 • 임피던스 미스매치(impedance mismatch) 없음 • 애그리거트 간 참조는 ID • 비선점 잠금 32
  33. 33. 성능 • 단일 애그리것트 조회 à 스냅샷 • 복합 조회 à CQRS 33
  34. 34. SQL(ORM) vs 이벤트 소싱 • 변화되는 것 34 영역 적용 전 (RDBMS/ORM) 적용 후 도메인 객체 로딩 SQL : SELECT 쿼리 ORM : 프레임워크가 매핑 설정을 이용해서 SELECT 쿼리 실행 - 이벤트로부터 도메인 객체 생성 - 도메인 객체의 이벤트 핸들러를 이용해 상태 변경 반영 도메인 기능 SQL : 서비스 클래스 ORM : (일부) 엔티티 클래스 - 도메인 객체가 수행 - 상태 변경을 위한 이벤트 생성 상태 변경 반영 (데이터 변경) SQL : Insert/Update/Delete 쿼리 ORM : 엔티티 프로퍼티를 변경하면 ORM 프레임워크가 알맞은 쿼리 실행 - 도메인 객체가 발생한 이벤트를 저장소에 보관
  35. 35. 장점 • DB에 의존적이지 않은 도메인 코드 구현 – 테이블이나 ORM 기술의 제한/제약에서 벗어남 • 기능 변경 – 하위 호환 처리가 상대적으로 쉬움 – 이벤트로부터 완전히 새로운 도메인 객체의 생성도 가능 • 버그 추적 용이 – 이벤트를 차례대로 검사하면서 버그 원인 추적 가능 • 객체 지향/DDD와 좋은 궁합 – 복잡한 도메인을 객체 지향적으로 구현하기에 좋음 • CQRS와 좋은 궁합 – 조회 관련 코드를 도메인에서 분리 – 조회 모델 분리로 조회 성능 향상 가능 35
  36. 36. 단점 • 익숙하지 않음 – SQL 위주(데이터 중심) 개발 성향인 경우 적응 힘듬 • 단순 모델에는 적합하지 않음 – 단순 모델에 적용하기엔 구현이 복잡해짐 • 도구 부족 – 이벤트 소싱과 CQRS 지원 프레임워크 부족 • 운영시 어려움 – 이벤트 데이터만으로는 최신 상태의 빠른 확인 불가 • CQRS 필수! 36
  37. 37. 37 두 번째 수다 정리
  38. 38. 38 세 번째 수다 SAGA
  39. 39. 길게 실행되는 프로세스 Long Running Business Process 39 주문하기 상품보내기 배송시작알리기 구매확정 요청하기
  40. 40. 길게 실행되는 프로세스 40 주문하기 상품보내기 배송시작 알리기 구매확정 요청하기 배송시작함주문함 배송시작집하하기 전달 배송완료함 입금하기 결제함
  41. 41. 길게 실행되는 프로세스/트랜잭션의 특징 • 여러 개의 작은 프로세스(트랜잭션)로 구성 • 하위 프로세스가 순서대로 실행되는 건 아님 • 여러 모듈/서비스가 (비동기로) 엮임 • 한 트랜잭션이 아님 • 실패는 롤백 대신 보상으로 처리 41
  42. 42. SAGA • 여러 하위 트랜잭션 집합으로 구성된 LLT – LLT: Long Lived Transaction – 단일 실행 단위 • 각 하위 트랜잭션은 단독 트랜잭션 – 하위 트랜잭션 단위로 일관성 보장 • 각 하위 트랜잭션은 서로 연관 • 하위 트랜잭션 실패시, 보상 트랜잭션 – 일부만 성공해도 끝나지 않음 42 * SAGAS (Hector Garcia-Molina, 1987)
  43. 43. 43 SAGA à 프로세스 매니저
  44. 44. 프로세스 매니저 • 여러 애그리거트/외부 시스템이 엮이는 긴 프로세스의 흐름 제어 – 각 구성 요소 간의 메시지 라우팅이 주된 역할 • 프로세스의 상태 보관 • 비즈니스 로직은 개별 구성 요소에서 처리 44
  45. 45. Saga / 프로세스 매니저 45 주문 프로세스 매니저 배송 서비스 결제 서비스 주문 애그리거트 재고 애그리거트 Paid Event 배송지시 OrderCreated Event Delivery Completed Event StockChanged Event 통지 서비스 배송 시작 통지 배송 완료
  46. 46. 구현 • 특정 이벤트에 Saga/프로세스 매니저 시작 • 수신한 이벤트에 따라 다음 기능 실행 – 실패시, 후속 보상 기능 실행 • 전체 프로세스가 끝나면 Saga/프로세스 매니저 종료 46
  47. 47. 상태 존재 à 프로세스별 인스턴스 • 에어카텔 상품 구매 예 47 public class BookingProcessManager { private BookingId bookingId; private BookingState hotelState; private BookingState airState; private BookingState carState; public void handle(BookingCreatedEvent evt) { this.bookingId = evt.getBookingId(); sendBookingRequest(); } public void handle(HotelBookedEvent evt) { hotelState = BookingState.BOOKED; notifyIfAllBooked(); } private void notifyIfAllBooked() { if (hotelState == BOOKED && airState == BOOKED && carState == BOOKED) { notifyBookingCompletion(); } }
  48. 48. 실패 보상 처리 • 에어카텔 호텔 예약 실패 예 48 public class BookingProcessManager { public void handle(HotelBookingFailedEvent evt) { cancelAirBooking(); cancelCar(); } private void cancelAirBooking() { if (airState == BOOKED) cancelAirBooking(); else airState = CANCEL_REQUIRED; } public void handle(AirBookedEvent evt) { if (airState == CANCEL_REQUIRED) { cancelAirBooking(); } else { airState = BOOKED; notifyIfAllBooked(); } }
  49. 49. 필요한 것 • SAGA/매니저 상태 영속화 – 상태가 유실되지 않아야 함 • 이벤트 à 해당 SAGA/매니저 – 효과적인 SAGA 검색 수단 필요 • SAGA 타임아웃 49
  50. 50. 특징 • 개별 애그리거트는 자기 자신의 도메인 로직에만 집중하면 됨 • 한 비즈니스 프로세스와 관련된 흐름 제어가 한 곳에 모임 – 프로세스 변경 용이 • (주로) 비동기 이벤트 기반 • SAGA/프로세스 매니저 인스턴스 관리 위한 기반 프레임워크 필요 50
  51. 51. 51 세 번째 수다 정리
  52. 52. 52 마무리

×