You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
79f45f 커밋 기준 AzureEventSourcedRepository_specs.SaveAndPublish_is_concurrency_safe 테스트 케이스는 실패한다. 영속된 후 이벤트가 발행되지 않는 경우가 발생한다. 이 문제는 메시지 분할(partitioning)이 적용된 시스템에서는 발생하지 않는다. 하지만 프레임워크가 메시지 분할을 강제하지 않기 때문에 이 문제는 해결되어야 한다.
우선 조치
CQRS Journey에서 소개하는 방식대로 영속 이벤트와 발행 대기 이벤트를 같은 파티션에 기록하고 복원 프로세스는 테이블 전체 검색(full scan)을 수행하도록 한다. 테이블 전체 검색 비용을 벤치마킹한 후 해결되어야 할 수준으로 판단되면 다음 방안을 검토한다.
테이블 구조
Type
Partition Key
Row Key
Transaction Id
Version
Persistent Event
{AggregateType}-{AggregateId}
{Version}
{TransactionId}
Pending Event
{AggregateType}-{AggregateId}
Pending-{Version}
{TransactionId}
{Version}
Publish Queue Item
{AggregateType}-Publish-{AggregateId}
{Version}-{TransactionId}
{TransactionId}
{Version}
Persistent Events와 Pending Events가 같은 파티션에 존재하면 명령 원자성을 보장받으므로 SQL 구현체와 유사한 매커니즘을 적용할 수 있다. 이것은 CQRS Journey에서 소개하는 방식이다. 하지만 이 방식은 영속 후 발행되지 못한 이벤트를 찾기 위해 테이블 전체 검색(full scan)이 수행되므로 큰 비용이 소비된다. 이 문제를 해결하기 위해 발행 작업 대기열을 나타내는 별도의 파티션(Publish Queue Item)을 만든다. 이 때 해결해야 할 문제는 작업 대기열을 나타내는 파티션은 이벤트 파티션과 다르기 때문에 명령의 원자성이 보장되지 않아 동시성 상황에 대해 각종 불일치가 발생할 수 있다는 점이다.
기본 I/O 절차
마지막 버전 기준 Publish Queue Item 추가
Persistent Events & Pending Events 추가
Pending Events 순차적 삭제
Publish Queue Item 삭제
복원 프로세스
Publish Queue Item과 동일한 버전의 Persistent Event 엔터티가 존재하지 않으면 해당 대기열 항목을 죽은 작업으로 판단한다.(이 경우 아직 진행중인지 죽은 작업인지 불명확한 상태로 분류해야 하는 것 아닌가?)
Publish Queue Item과 동일한 버전의 Persistent Event 엔터티의 TransactionId가 일치하지 않으면 해당 대겨얼 항목을 죽은 작업으로 판단한다.
예외 사례
AggregateId와 TransactionId에는 GUID가 사용되지만 편의상 짧게 적는다.
Case 1
AggregateType
AggregateId
User
1
Process 1 Transaction A 시작
Process 110 버전 기준 Publish Queue Item 추가
Process 1CRASH!
Type
Partition Key
Row Key
Transaction Id
Version
Publish Queue Item
User-Publish-1
10-A
A
10
복원 프로세스는 대기열 항목은 동일 버전의 Persistent Event 엔터티가 존재하지 않기 때문에 죽은 작업임을 판단할 수 있다.
Case 2
AggregateType
AggregateId
User
1
Process 1 Transaction A 시작
Process 110 버전 기준 Publish Queue Item 추가
Process 2 복원 프로세스 시작
Process 2 복원 프로세스가 Publish Queue Item를 죽은 작업으로 오판해 삭제
Process 1 Persistent Events & Pending Events 추가
Process 1CRASH!
Type
Partition Key
Row Key
Transaction Id
Version
Persistent Event
User-1
10
A
Pending Event
User-1
Pending-10
A
10
복원 프로세스는 대기열 항목이 없기 때문에 대기 이벤트를 발행할 수 없다.
Case 3
AggregateType
AggregateId
User
1
Process 1 Transaction A 시작
Process 110 버전 기준 Publish Queue Item 추가
Process 1CRASH!
Process 1 Transaction B 시작
Process 110 버전 기준 Publish Queue Item 추가
Process 1 Persistent Events & Pending Events 추가
Process 1 Pending Events 순차적 삭제
Process 1 Publish Queue Item 삭제
Process 1 Transaction B 종료
Type
Partition Key
Row Key
Transaction Id
Version
Persistent Event
User-1
10
B
Publish Queue Item
User-Publish-1
10-A
A
10
복원 프로세스는 대기열 항목과 동일 버전의 Persistent Event 엔터티의 TransactionId가 일치하지 않기 때문에 해당 대기열 항목이 죽은 작업임을 판단할 수 있다.
The text was updated successfully, but these errors were encountered:
79f45f
커밋 기준AzureEventSourcedRepository_specs.SaveAndPublish_is_concurrency_safe
테스트 케이스는 실패한다. 영속된 후 이벤트가 발행되지 않는 경우가 발생한다. 이 문제는 메시지 분할(partitioning)이 적용된 시스템에서는 발생하지 않는다. 하지만 프레임워크가 메시지 분할을 강제하지 않기 때문에 이 문제는 해결되어야 한다.우선 조치
CQRS Journey에서 소개하는 방식대로 영속 이벤트와 발행 대기 이벤트를 같은 파티션에 기록하고 복원 프로세스는 테이블 전체 검색(full scan)을 수행하도록 한다. 테이블 전체 검색 비용을 벤치마킹한 후 해결되어야 할 수준으로 판단되면 다음 방안을 검토한다.
테이블 구조
{AggregateType}-{AggregateId}
{Version}
{TransactionId}
{AggregateType}-{AggregateId}
Pending-{Version}
{TransactionId}
{Version}
{AggregateType}-Publish-{AggregateId}
{Version}-{TransactionId}
{TransactionId}
{Version}
Persistent Events와 Pending Events가 같은 파티션에 존재하면 명령 원자성을 보장받으므로 SQL 구현체와 유사한 매커니즘을 적용할 수 있다. 이것은 CQRS Journey에서 소개하는 방식이다. 하지만 이 방식은 영속 후 발행되지 못한 이벤트를 찾기 위해 테이블 전체 검색(full scan)이 수행되므로 큰 비용이 소비된다. 이 문제를 해결하기 위해 발행 작업 대기열을 나타내는 별도의 파티션(Publish Queue Item)을 만든다. 이 때 해결해야 할 문제는 작업 대기열을 나타내는 파티션은 이벤트 파티션과 다르기 때문에 명령의 원자성이 보장되지 않아 동시성 상황에 대해 각종 불일치가 발생할 수 있다는 점이다.
기본 I/O 절차
복원 프로세스
예외 사례
Case 1
User
1
Process 1
TransactionA
시작Process 1
10
버전 기준 Publish Queue Item 추가Process 1
CRASH!User-Publish-1
10-A
A
10
복원 프로세스는 대기열 항목은 동일 버전의 Persistent Event 엔터티가 존재하지 않기 때문에 죽은 작업임을 판단할 수 있다.
Case 2
User
1
Process 1
TransactionA
시작Process 1
10
버전 기준 Publish Queue Item 추가Process 2
복원 프로세스 시작Process 2
복원 프로세스가 Publish Queue Item를 죽은 작업으로 오판해 삭제Process 1
Persistent Events & Pending Events 추가Process 1
CRASH!User-1
10
A
User-1
Pending-10
A
10
복원 프로세스는 대기열 항목이 없기 때문에 대기 이벤트를 발행할 수 없다.
Case 3
User
1
Process 1
TransactionA
시작Process 1
10
버전 기준 Publish Queue Item 추가Process 1
CRASH!Process 1
TransactionB
시작Process 1
10
버전 기준 Publish Queue Item 추가Process 1
Persistent Events & Pending Events 추가Process 1
Pending Events 순차적 삭제Process 1
Publish Queue Item 삭제Process 1
TransactionB
종료User-1
10
B
User-Publish-1
10-A
A
10
복원 프로세스는 대기열 항목과 동일 버전의 Persistent Event 엔터티의 TransactionId가 일치하지 않기 때문에 해당 대기열 항목이 죽은 작업임을 판단할 수 있다.
The text was updated successfully, but these errors were encountered: