DDD, Saga & Event-sourcing : 보상 조치가 단순히 이벤트 저장소에서 삭제 될 수 있습니까?


15

위의 질문은 아마도 몇 가지 '무엇입니까?'를 제기하지만, 설명하려고 노력할 것입니다.

이벤트 소싱 (DDD- 개념)과 함께 기본적으로 Saga-pattern ( http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf ) 과 같은 두 가지 관련 개념을 설명하려고합니다. : http://en.wikipedia.org/wiki/Domain-driven_design )

함께 포장하는 좋은 게시물 : https://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/

나는 잠시 후에 질문에 도달하고 있지만, 내가 이해하는 것을 먼저 요약하려고 노력해야한다고 생각합니다 (잘못 될 수 있으므로 그럴 경우 수정하십시오). 질문으로 시작 :

  1. Saga 패턴은 특정 활동 (최종 사용자, 자동화 된 등 본질적으로 데이터를 변경하려는 모든 것)이 해당 활동을 비즈니스 활동으로 나누고 각 활동을 메시지로 메시지 버스로 보내는 일종의 브로커입니다. 차례로 관리 할 각 집계 루트로 보냅니다.
  2. 이러한 집계 루트는 완전히 자율적으로 작동 할 수 있습니다 (문제의 분리, 확장 성 등).
  3. Saga 인스턴스 자체에는 비즈니스 로직이 포함되어 있지 않습니다. 비즈니스 로직은 활동을 보내는 총계 루트에 포함되어 있습니다. Saga에 포함 된 유일한 'logic'은 '프로세스'-logic (주로 Statemachine으로 구현 됨)으로, 수신 된 작업 (및 후속 이벤트)에 따라 수행 할 작업 (예 : 전송할 활동)을 결정합니다.
  4. 사가 패턴은 일종의 분산 트랜잭션 패턴을 구현합니다. 즉, 집계 루트 중 하나 (서로 다른 존재를 몰라도 자율적으로 다시 작동)가 실패하면 전체 조치를 롤백해야 할 수도 있습니다.
  5. 이것은 활동 보고서가 완료되면 사가에게 모든 집계 루트를 갖음으로써 구현됩니다. (오류뿐만 아니라 성공한 경우)
  6. 모든 집계 루트가 성공을 반환하는 경우 Saga가 다음에 수행 할 작업을 결정하거나 완료 한 경우 내부 상태 시스템
  7. 실패시, Saga는 마지막 조치에 참여한 모든 집계 루트에 소위 보상 조치, 즉 각 집계 루트가 수행 한 마지막 조치를 실행 취소하는 조치를 발행합니다.
  8. 액션이 "플러스 1 투표"인 경우 단순히 '마이너스 1 투표'를 수행하는 것일 수도 있지만 블로그 게시물을 이전 버전으로 복원하는 것처럼 더 복잡 할 수 있습니다.
  9. 이벤트 소싱 (두 가지를 결합한 블로그 게시물 참조)은 각 집계 루트가 중앙 집중식 이벤트 저장소에 수행하는 각 활동의 결과를 외부에 저장하는 것을 목표로합니다 (이 컨텍스트에서는 변경을 '이벤트'라고 함).
  10. 이 이벤트 저장소는 '진리의 단일 버전'이며 저장된 이벤트를 본질적으로 반복하여 모든 엔티티의 상태를 재생하는 데 사용할 수 있습니다 (기본적으로 이벤트 로그처럼).
  11. 두 가지를 결합하면 (즉, 집합 루트가 이벤트 소싱을 사용하여 Saga에 다시보고하기 전에 변경 사항을 외부에서 저장하도록 허용) 많은 가능성이 가능합니다.

한 번에 파악하기가 많기 때문에 어깨에서 이것을 벗겨야한다고 생각했습니다. 이 맥락 / 마인드가 주어지면 (다시 잘못하면 정정하십시오)

질문 : 집계 루트가 보상 조치를 수신하고 해당 집계 루트가 이벤트 소싱을 사용하여 상태 변경을 아웃소싱 한 경우 모든 상황에서 보상 조치가 이벤트 저장소의 마지막 이벤트를 삭제하지는 않습니다. 주어진 집계 루트? (지속 구현으로 인해 삭제가 가능하다고 가정)

그것은 나에게 많은 의미가 있으며 (이 조합의 또 다른 큰 이점이 될 것입니다), 내가 말했듯 이이 개념에 대한 잘못 / 불완전한 이해에 근거하여 이러한 가정을 할 수 있습니다.

나는 이것이 오래 걸리지 않기를 바랍니다.

감사.

답변:


9

이벤트 저장소에서 이벤트를 삭제해서는 안됩니다. 이것들은 일어난 일을 나타냅니다. 지금 어떤 일이 발생하면 그 사실도 알아야하므로 집계를 이전 상태로 되돌릴 수있는 이벤트를 추가하십시오. 데이터베이스에서 정보를 삭제하는 것이 유감입니다.

그레그 젊음과 제거 된 아이템의 카트 예를 생각해보십시오. 보상 조치에 대한 정보는 내일이 될 수 있습니다 ..

사가는 내가 아는 한 모든 것이 정확합니다. saga를 상태 머신으로 생각해야합니다. 그것은 단지 그렇게합니다.

사가가 총계에게 무언가를하도록 명령하는 것은 사령부입니다. 이 행동 중 행사가있을 것입니다. 이 이벤트는 필요한 수정 조치이거나 일부 사용자가 수행 할 조치를 결정하기 위해보기에서 비정규 화해야 할 수도 있습니다.

비즈니스 규칙에 따라 다릅니다. 쉬운 해결책이 있습니다. 집합적인 루트는 그러한 경우에, 또는 그렇게 선택하거나 프로그래밍 방식으로 수행하기에는 너무 복잡하다는 것을 알기 때문에 (개발 비용이 너무 높음)이를 일부 사용자에게 제안 할 수 있습니다 다른 행동 중에서 선택할 수 있습니다. 모든 것은 보상 조치의 맥락에 달려 있습니다. 이것은 순수한 비즈니스 규칙입니다. 이 경우 나 그 경우에 어떻게해야합니까? 이것은 도메인 전문가에게 물어보고 자동 솔루션을 개발하는 것이 더 나은지 또는 솔루션이 사용자에게 Ronald R.에게 물어 보는 것인지를 선택하는 것입니다. 그가 보통이 질문에 대답하는 사람이기 때문입니다.


집계는 되돌릴 상태를 어떻게 알 수 있습니까? 이벤트 저장소 또는 다른 것에 대해 쿼리 할 수 ​​있습니까?
Geert-Jan

되 돌리지 말고 다른 이벤트를 추가하십시오. 사가가 총계에게 무언가를하도록 명령하는 것은 사령부입니다. 이 행동 중 행사가있을 것입니다.
Arthis

네 이해합니다 "복귀"는 아마 잘못 선택되었을 것입니다. 다음을 고려하십시오. 무엇보다도 문서 게시 / 승인 흐름을 모델링하기 위해 Sagas와 함께 이벤트 소싱을 사용할 수 있습니다. 편집자가 궁극적으로 BlogBodyChanged 이벤트로 유지되는 ChangeBlogBody 조치를 이벤트 저장소에 보낸 경우 어떻게됩니까? 그 후 어떤 이유로 든 보상 조치가 발행됩니다. Aggregate는 ChangeBlogBody-action이 발행되기 직전에 블로그 본문의 내용을 발생시키는 보상 이벤트를 어떻게 알 수 있습니까?
Geert-Jan

비즈니스 규칙에 따라 다릅니다. 쉬운 해결책이 있습니다. 집합적인 루트는 그러한 경우에, 또는 그렇게 선택하거나 프로그래밍 방식으로 수행하기에는 너무 복잡하다는 것을 알고 있습니다 (개발 비용이 너무 높음). 다른 행동 중에서 선택할 수 있습니다.
Arthis

모든 것은 보상 조치의 맥락에 달려 있습니다. 이것은 순수한 비즈니스 규칙입니다. 이 경우 나 그 경우에 어떻게해야합니까? 이것은 도메인 전문가에게 물어보고 자동 솔루션을 개발하는 것이 더 나은지 또는 사용자에게 Ronald R.에게 물어 보는 것이 좋은지 선택하십시오. 그는 보통이 질문에 대답하는 사람이기 때문입니다.
Arthis

6

완성을 위해 Martin Fowler의 관련 스 니펫을 포함하여 상태를 되 돌리는 방법에 대해 생각했습니다.

앞으로 진행되는 이벤트뿐만 아니라 자신을 되돌릴 수도있는 경우가 종종 있습니다.

반전은 이벤트가 차이의 형태로 캐스트 될 때 가장 간단합니다. 예를 들어 "Martin의 계정을 $ 110으로 설정"과 반대로 "Martin의 계정에 $ 10 추가"가 있습니다. 전자의 경우에는 $ 10을 빼서 되돌릴 수 있지만 후자의 경우 계정의 과거 가치를 재현하기에 충분한 정보가 없습니다.

입력 이벤트가 차이 접근 방식을 따르지 않는 경우 이벤트는 처리 중 반전에 필요한 모든 것을 저장해야합니다. 변경된 값에 이전 값을 저장하거나 이벤트의 차이를 계산하여 저장하여이를 수행 할 수 있습니다.

보낸 사람 : http://martinfowler.com/eaaDev/EventSourcing.html


1

개념적으로 :

  • 사건은 일어난 일입니다. 과거는 바꿀 수 없습니다.
  • 명령은해야 할 일입니다. 명령이 발생하지 않을 수 있습니다 (거부 될 수 있음).

이벤트의 응용 프로그램 상태가 변경되도록하는 다른 명령 (보상 조치)을 실행하여 미래 상태 만 변경할 수 있습니다.

질문을 "혼동"시키려면 다음 문구 "마지막 이벤트 삭제"에 대해 생각해보십시오.

  • 마지막 이벤트가 삭제되지 않은 경우 어떻게됩니까? 삭제 후 다른 이벤트가 발생한 경우 어떻게합니까? 이러한 이벤트도 변경해야합니다 (기본 상태는 이벤트를 삭제하여 변경되었으므로).
  • 이벤트가 외부 시스템으로 전송되면 어떻게됩니까? 다른 이벤트를 보내는 것 이외의 상태를 수정할 수있는 권한이 없을 수도 있습니다.

즉, CQRS 패턴 내에서 이벤트를 삭제할 수있는 옵션이 없습니다.

스냅 샷 상태 (해당 상태로 이어지는 모든 이벤트를 기반으로 함)를 작성하여 이벤트 저장소를 축소 할 수 있지만이 물리적 측면은 이벤트 개념과 관련이 없습니다.


0

Geert-Jan, 보상 조치도 해당 이벤트를 간단하게 삭제할 수 있다고 생각합니다. 이해하기 쉽고 Event Sourcing 디자인 패턴의 또 다른 이점 인 Compensating Transaction 디자인 패턴을보다 쉽게 ​​구현할 수 있습니다.

일부는 이벤트 삭제가 이벤트 소싱 또는 CQRS의 "원칙"을 위반한다고 말합니다. 나는 그것이 제한적인 일반화라고 생각합니다. 취소되는 글로벌 트랜잭션 범위 내에서 이벤트가 작성된 경우 이벤트를 삭제해도 괜찮습니다. 의사 코드를 고려하십시오.

try {
    newEvents = processMycommand(myCommand)
    for (Event newEvent : newEvents)
        EventStore.insertEvent(newEvent);
} catch (Exception e) {
    EventStore.rollback();
}

이벤트 저장소가 트랜잭션 데이터베이스라고 가정하십시오. 의사 코드에서 첫 번째 이벤트를 삽입 한 상황을 상상할 수 있지만 두 번째 이벤트를 삽입하려고 할 때 예외가 발생했습니다. 롤백 명령은 자연스럽게 첫 번째 이벤트 삽입을 되돌립니다. 합리적입니까?

ACID 데이터베이스 트랜잭션 (커밋 / 롤백을 통한 트랜잭션)에 적합한 경우 보상 트랜잭션에 적합하지 않은 이유는 무엇입니까?

글로벌 사가 트랜잭션을 실행할 때 데이터 변경을 취소 할 수 있습니다 (보상). 트랜잭션이 완료되지 않았기 때문에 트랜잭션 중에 생성 된 이벤트를 유지할 필요가 없습니다.

이제 보상이 이벤트를 삭제하려고 시도하고 해당 이벤트가 오브젝트의 최신 이벤트가 아닌 경우 삭제가 발생하지 않아야합니다. 그러나 일반적으로 특히 읽기 집약적 인 솔루션에서는 그럴 가능성이 적습니다.


0

이벤트 스토리지는 저장하려는 데이터 일 뿐이라는 생각을 가지고 놀자. 예를 들어 하드 드라이브를 가질 수 있으며 처음부터 시작하여 데이터를 쓸 수 있습니다. 이벤트가있을 때마다 이전 데이터를 추가하므로 지난번에 중지 한 디스크에 계속 쓰기 만하면됩니다. 이벤트를 제거하려면 돌아가서 디스크에서 해당 부분을 제거하고 간격을 두십시오. 자체적으로 되돌아 가면 이벤트 저장 속도가 느려지지만 그와 함께 살 수 있습니다. 파일 시스템을 사용하면 후자의 이벤트로 간격을 메우려 고 시도하므로 조각화 된 스토리지가 느려지거나 조각 모음을 수행 할 수 있습니다. 그들 중 어느 것도 우리가 좋아하는 것이 아닙니다. 데이터베이스에 대해 이야기하는 경우 이벤트를 저장하기 위해 추가 전용 데이터베이스 대신 관계형 데이터베이스를 사용하면 다음과 같은 결과를 얻을 수 있습니다.

여기에 이미지 설명을 입력하십시오 심판 : https://cambridge-intelligence.com/bringing-time-series-data-to-life-with-keylines/

Ofc. 정상적인 사이트에서는 이것이 중요하지 않지만 이러한 솔루션은 페이스 북, Google 등과 같은 거대한 웹 사이트를 위해 설계되었습니다. 따라서 실제로 추가 전용 데이터베이스에서 이벤트를 삭제하는 방법과 방법은 무엇입니까? 당신은 이벤트를 변경하거나 방지하기 위해 타임머신을 구축하고 시간을 거슬러 올라가는 것과 같은 보상을 호출합니까 ???

아파 익. 이를 해결하는 유일한 방법은 원하지 않는 이벤트를 제외하고 새 이벤트 스토리지를 제거한 후에 새 이벤트 스토리지를 작성하는 것입니다. 그러나 이것은 단일 이벤트를 제거하는 극단적 인 솔루션입니다. 우리가 GDPR에 관해 이야기하고 있다면, 내가 아는 유일한 좋은 해결책은 이벤트 스토리지에 암호화 된 개인 데이터를 저장하고 다른 데이터베이스에서 암호화 키를 제거하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.