최종적으로 일관된 작업에서 하나 이상의 단계가 실패하는 경우 이 패턴을 사용하여 작업을 실행 취소합니다. 복잡한 비즈니스 프로세스 및 워크플로를 구현하는 클라우드 호스팅 애플리케이션은 일반적으로 최종 일관성 모델을 따르는 작업을 사용합니다.
컨텍스트 및 문제점
클라우드 애플리케이션은 다양한 지리적 위치에 있는 다양한 데이터 원본에 분산된 데이터를 자주 수정합니다. 분산 환경에서 경합을 방지하고 성능을 향상시키려면 애플리케이션은 강력한 트랜잭션 일관성 대신 최종 일관성을 구현해야 합니다. 최종 일관성 모델에서 일반적인 비즈니스 작업은 일련의 개별 단계로 구성됩니다. 이러한 단계에서 시스템 상태의 전체 보기가 일치하지 않을 수 있습니다. 그러나 모든 단계가 완료되면 시스템이 다시 일관성을 유지해야 합니다.
단계 오류를 처리하면 최종 일관성 모델에서 중요한 과제가 발생합니다. 오류가 발생한 후 완료된 작업 단계에서 작업을 실행 취소해야 할 수 있습니다. 그러나 다른 동시 애플리케이션 인스턴스가 데이터를 변경할 수 있으므로 항상 데이터를 롤백할 수는 없습니다. 동시 인스턴스가 데이터를 변경하지 않는 경우에도 원래 상태를 복원하는 것보다 단계를 실행 취소하는 것이 더 복잡할 수 있습니다. 비즈니스별 규칙을 적용해야 할 수도 있습니다. 예를 들어 여행 웹 사이트 예제를 참조하세요.
최종 일관성을 구현하는 작업이 여러 데이터 저장소에 걸쳐 있는 경우 각 데이터 저장소에 액세스하여 변경 내용을 실행 취소해야 합니다. 시스템이 일관성 없는 상태를 유지하지 않도록 하려면 모든 데이터 저장소에서 작업을 안정적으로 실행 취소해야 합니다.
최종 일관성을 구현하는 작업이 영향을 받는 데이터를 데이터베이스에 항상 저장하지는 않습니다. 예를 들어 SOA(서비스 지향 아키텍처) 환경에서 작업은 서비스에서 작업을 호출하고 서비스가 보유하는 상태를 변경할 수 있습니다. 작업을 실행 취소하려면 첫 번째 작업의 효과를 되돌리기 위해 서비스를 다시 호출하는 작업이 포함될 수 있는 이 상태 변경도 실행 취소해야 합니다.
해결 방법
원래 작업에서 완료된 단계의 효과를 실행 취소하는 보상 트랜잭션을 구현합니다. 단순히 시스템을 원래 상태로 복원할 수 있다고 생각할 수도 있지만, 이 방법은 다른 동시 애플리케이션 인스턴스의 변경 내용을 덮어쓸 수 있습니다. 대신, 보상 트랜잭션은 동시 작업을 지능적으로 고려해야 합니다. 이 프로세스는 일반적으로 애플리케이션에 따라 달라 집니다 및 원래 작업에 따라 달라 집니다.
워크플로를 사용하여 보정이 필요한 최종적으로 일관된 작업을 구현할 수 있습니다. 원래 작업이 실행되면 시스템은 각 단계 및 실행 취소 방법에 대한 정보를 기록합니다. 작업이 실패하면 워크플로가 완료된 단계를 되감고 각 단계를 반대로 바뀝니다.
각 단계는 별도의 작업이지만 결국 일관된 작업을 구성합니다. 시스템은 각 단계에 대해 단계 및 해당 실행 취소 작업을 수행해야 합니다. 고객이 취소하는 경우 이러한 실행 취소 작업은 보상 트랜잭션으로 실행할 수 있습니다.
단일 단계 오류가 항상 보상 트랜잭션을 사용하여 전체 시스템을 롤백해야 하는 것은 아닙니다. 예를 들어 여행 웹 사이트 시나리오에서 고객은 F1, F2 및 F3 항공편을 예약하지만 호텔 H1에서 객실을 예약하지 못합니다. 고객에게 다른 호텔의 객실을 제공하는 것이 항공편을 취소하는 것이 좋습니다. 고객은 여전히 취소를 선택할 수 있으며, 이로 인해 보상 트랜잭션이 트리거되어 항공편 예약을 취소할 수 있습니다. 그러나 고객은 시스템이 아닌 이 결정을 내려야 합니다. 의사 결정이 큰 영향을 미치거나 안정적으로 자동화하기 어려운 경우 의사 결정 프로세스에 인간을 포함합니다.
다음과 같은 중요한 사항을 고려합니다.
보상 트랜잭션은 원래 작업의 정확한 역순으로 작업을 실행 취소할 필요가 없습니다.
일부 실행 취소 단계를 병렬로 수행할 수 있습니다.
비즈니스별 규칙을 적용해야 할 수도 있습니다. 예를 들어 항공편 예약을 취소해도 고객에게 완전한 환불을 받을 수 없습니다.
이 방법은 Saga 분산 트랜잭션 패턴과 유사합니다.
보상 트랜잭션은 결국 일관된 작업이며 실패할 수 있습니다. 시스템은 실패 지점에서 보상 트랜잭션을 다시 시작할 수 있도록 진행률을 기록해야 합니다. 다시 시도하면 단계가 여러 번 실행될 수 있으므로 각 단계를 idempotent 명령으로 디자인합니다.
때로는 수동 개입이 실패한 단계에서 복구하는 유일한 방법입니다. 이러한 경우 시스템은 오류 원인에 대한 자세한 정보를 포함하는 경고를 발생시켜야 합니다.
문제 및 고려 사항
이 패턴을 구현하는 방법을 결정할 때 다음 사항을 고려합니다.
최종 일관성을 구현하는 작업의 단계가 실패하는 경우를 확인하기가 쉽지 않을 수 있습니다. 단계가 즉시 실패하지 않고 차단될 수 있습니다. 시간 제한 메커니즘을 구현해야 할 수도 있습니다.
보정 논리를 일반화하는 것은 쉽지 않습니다. 보상 트랜잭션은 애플리케이션별로 다릅니다. 실패한 작업에서 각 단계의 효과를 실행 취소할 수 있는 충분한 정보가 있는 애플리케이션에 의존합니다.
보상 트랜잭션이 항상 작동하는 것은 아닙니다. 보상 트랜잭션의 단계를 idempotent 명령으로 정의하여 보상 트랜잭션 자체가 실패할 경우 반복할 수 있도록 합니다.
단계를 처리하는 인프라는 다음 조건을 충족해야 합니다.
원래 작업과 보완 트랜잭션 모두에 복원력이 있습니다.
실패한 단계를 보상하는 데 필요한 정보는 손실되지 않습니다.
보정 논리 진행률을 안정적으로 모니터링합니다. 보상 트랜잭션은 원래 작업이 커밋된 후에 실행되며 다른 트랜잭션은 중간 상태를 변경할 수 있습니다. 따라서 원래 작업과 상쇄 작업을 엔드 투 엔드로 연관시키고 감사할 수 있는지 확인하십시오.
보상 트랜잭션이 원래 작업을 시작할 때 시스템 데이터를 해당 상태로 반드시 반환하지는 않습니다. 대신 트랜잭션은 작업이 실패하기 전에 성공적으로 완료된 작업을 보정합니다.
보상 트랜잭션 단계가 항상 원래 작업을 정확히 반대 순서로 되돌리는 것은 아닙니다. 예를 들어 한 데이터 저장소가 다른 데이터 저장소보다 불일치에 더 민감할 경우 먼저 해당 저장소에 대한 변경 내용을 실행 취소합니다.
일부 측정값은 성공률을 개선하는 데 도움이 될 수 있습니다. 작업을 완료하는 데 필요한 각 리소스에 시간 제한이 있는 단기 잠금을 배치할 수 있습니다. 이러한 리소스를 미리 확보한 다음 모든 리소스를 획득한 후에만 작업을 수행할 수 있습니다. 잠금이 만료되기 전에 모든 작업을 완료합니다.
더 많은 오류를 일시적으로 처리하는 재시도 논리는 보상 트랜잭션을 트리거하는 오류를 최소화하는 데 도움이 될 수 있습니다. 최종 일관성을 구현하는 작업의 단계가 실패하면 일시적 예외로 처리하고 단계를 다시 시도합니다. 단계가 반복적으로 실패하거나 복구할 수 없는 경우에만 작업을 중지하고 보정을 트리거합니다. 재시도 전략에 대한 자세한 내용은 일시적인 오류 처리를 참조하세요.
보상 트랜잭션을 구현할 때 최종 일관성을 구현하는 것과 유사한 많은 문제에 직면하게 됩니다. 자세한 내용은 조정 최소화를 참조하세요.
반환되지 않고 되돌릴 수 없는 단계의 명확한 지점을 정의합니다. 복잡한 워크플로에서는 외부 부작용 또는 법적 구속력이 있는 작업과 같은 일부 작업을 안전하고 의미 있는 실행 취소할 수 없습니다. 보상 가능한 단계와 돌이킬 수 없는 단계를 식별합니다. 모든 중요한 유효성 검사가 성공한 후에만 되돌릴 수 없는 단계가 수행되도록 워크플로를 디자인합니다.
이 패턴을 사용하는 경우
다음 경우에 이 패턴을 사용합니다.
비즈니스 작업은 여러 단계, 서비스 또는 데이터 저장소에 걸쳐 있으며 이후 단계가 실패할 경우 실행 취소해야 합니다. 이 시나리오는 최종 일관성 모델을 따르고 원자성 트랜잭션을 사용할 수 없는 장기 실행 워크플로에서 발생하는 경우가 많습니다.
오류 복구에는 간단한 데이터 롤백이 아닌 도메인별 논리가 필요한 경우가 많습니다. 작업을 취소할 때 보상 작업을 사용하려면 예약 취소 또는 부분 환불 발급과 같은 비즈니스 규칙을 적용해야 합니다.
이 패턴은 다음과 같은 경우에 적합하지 않을 수 있습니다.
작업은 안전하게 다시 시도될 수 있으며 대부분의 오류는 일시적입니다. 이러한 경우 재시도 논리만으로도 충분하며, 보상 트랜잭션은 불필요한 복잡성을 초래합니다.
시스템은 일시적인 불일치를 허용할 수 없거나 보정이 유효한 상태를 안정적으로 복원할 수 없습니다. 대신 모든 단계에서 강력한 일관성 메커니즘 또는 원자성 트랜잭션을 사용합니다.
워크로드 디자인
워크로드 디자인에서 보상 트랜잭션을 사용하여 Azure Well-Architected Framework 핵심 요소 다루는 목표와 원칙을 해결하는 방법을 평가합니다. 다음 표에서는 이 패턴이 각 핵심 요소의 목표를 지원하는 방법에 대한 지침을 제공합니다.
| 핵심 요소 | 이 패턴으로 핵심 목표를 지원하는 방법 |
|---|---|
| 안정성 설계 결정을 통해 워크로드가 오작동에 대한 복원력을 높일 수 있으며 오류가 발생한 후 완전히 작동하는 상태로 복구 되도록 할 수 있습니다. | 보정 작업은 데이터 변경 내용을 직접 롤백하거나, 트랜잭션 잠금을 끊거나, 네이티브 시스템 동작을 실행하여 효과를 되돌리는 등의 프로세스를 사용하여 중요한 워크로드 경로의 오작동을 해결합니다. - RE:02 중요 흐름 - RE:09 재해 복구 |
이 패턴이 하나의 기둥 내에서 절충을 도입하는 경우, 이를 다른 기둥의 목표와 비교해서 고려해 보세요.
예시
다음 다이어그램에서는 보상 트랜잭션 패턴의 실제 Azure 구현을 보여 줍니다. 다른 구현은 워크로드 요구 사항에도 작동할 수 있습니다. Azure Container Apps 실행되는 오케스트레이터는 Azure Service Bus 통해 명령을 전송하여 장기 실행 워크플로의 각 단계를 조정합니다. 각 전달 단계가 성공하면 오케스트레이터는 워크플로를 다시 시작, 상관 관계 및 감사할 수 있도록 실행 상태와 해당 보정 작업을 Azure Cosmos DB 모두 기록합니다.
이 모델은 먼저 재시도를 사용하여 진행률을 유지합니다. 단계가 실패하면 오케스트레이터는 일시적인 오류에 대해 재시도 논리를 적용하고 원래 작업을 계속하려고 시도합니다. 보정은 재시도가 소진되거나 실패가 비일시적으로 분류되는 경우와 같이 전달 진행이 불가능한 경우에만 호출됩니다.
비즈니스별 규칙은 즉각적인 보상보다 진행 상황을 선호할 수도 있습니다. 단계가 실패하면 오케스트레이터는 워크플로를 롤백하는 대신 동등한 서비스 또는 대체 옵션을 대체하는 등의 대체 경로를 선택할 수 있습니다. 영향이 높거나 모호한 경우 대체 경로를 계속할지 또는 보상을 트리거할지 결정하기 전에 사용자 검토를 위해 워크플로를 일시 중지할 수 있습니다. 이 방법은 보상을 최후의 수단으로 처리하고 도메인 규칙이 복구 결정을 내릴 수 있도록 합니다.
일반적인 시퀀스에서 오케스트레이터는 Service Bus(1단계와 2단계)를 통해 단계 메시지를 보내고, 성공적인 결과를 수신하고, 전달 및 보정 메타데이터를 Azure Cosmos DB 저장합니다.
다음 두 가지 방법으로 보정을 트리거할 수 있습니다.
동일한 워크로드의 이후 단계가 실패하고 이전에 성공한 단계를 실행 취소해야 하는 경우 이 보상은 단계가 규칙 검증 실패와 같은 비즈니스 오류를 반환하거나 모든 기술적인 재시도가 소진된 후 메시지가 비인출 메시지 큐로 이동된 즉시 발생할 수 있습니다.
후속 클라이언트가 완료된 작업을 취소하도록 명시적으로 요청하는 경우
두 경우 모두 오케스트레이터는 저장된 보상 레코드를 읽고 해당 서비스에 보상 명령을 보냅니다. 보상 단계가 일시적으로 실패하는 경우 Service Bus 재시도는 인시던트를 에스컬레이션하지 않고 완료할 수 있습니다.
반복해서 재시도해도 여전히 실패하는 경우 Service Bus는 메시지를 배달 못한 편지 큐로 이동시키고 실패 세부 정보를 보존합니다. 오케스트레이터 또는 전용 데드레터 프로세서는 경고를 발생시키고 실패 이유 및 상관 관계 ID를 포함한 구조적 원격 분석 데이터를 Azure Monitor 및 Log Analytics에 발송하여 Application Insights에 표시할 수 있게 합니다. 이 운영 경로는 팀이 오류를 진단하고, 수동 개입의 필요성을 결정하고, 원래 흐름과 보정 흐름 모두에서 추적 가능성을 유지하는 데 도움이 됩니다.
워크플로는 명확하고 위험 수준이 낮은 조건에 대한 보상을 자동으로 시작하거나, 상황이 모호하거나, 영향이 높거나, 수동 결정이 필요한 경우 사용자 검토를 위해 일시 중지할 수 있습니다.
구성 요소 간에 관리 ID 및 Microsoft Entra ID 기반 권한 부여를 사용하여 공유 비밀을 방지하고 최소 권한 액세스를 적용합니다. 간소화된 참조 다이어그램을 만들 때 이러한 ID 및 권한 부여 컨트롤을 명시적 흐름 단계가 아닌 기준 구현 문제로 처리합니다. 다이어그램은 오케스트레이션, 재시도, 보정 및 오류 처리에 초점을 맞췄습니다.
관련 리소스
마이크로 서비스에 대한 데이터 고려 사항: 최종 일관성 및 부분 오류가 분산 시스템에 내재된 이유를 알아봅니다. 보상 트랜잭션 패턴은 작업이 여러 서비스에 걸쳐 있을 때 이러한 오류를 처리하는 구체적인 메커니즘을 제공합니다.
Azure Cosmos DB와 함께 사용하는 트랜잭셔널 아웃박스 패턴: 보상 트랜잭션이 이벤트나 명령을 신뢰성 있게 게시해야 할 때 이 패턴을 사용합니다. 상태 변경 및 메시지가 원자성으로 기록되어 메시지 손실을 방지하는 데 도움이 됩니다.
자체 복구를 위한 디자인: 애플리케이션에 대한 자동 복구 접근 방식의 일부로 보상 트랜잭션을 사용합니다.
Scheduler 에이전트 감독자 패턴: 이 패턴을 사용하여 분산 서비스 및 리소스에서 비즈니스 작업을 수행하는 복원력 있는 시스템을 구현합니다. 이러한 시스템은 때때로 작업을 실행 취소하기 위해 트랜잭션을 보상해야 합니다.
다시 시도 패턴: 이 패턴을 사용하여 일시적인 오류를 처리하고 트랜잭션을 보상할 필요성을 최소화합니다.
Saga 분산 트랜잭션 패턴: 이 패턴을 사용하여 분산 트랜잭션의 마이크로 서비스에서 데이터 일관성을 관리합니다. Saga는 오류 복구를 위해 보상 트랜잭션을 사용합니다.
파이프 및 필터 패턴: 복합 작업을 재사용 가능한 단계로 분해할 때 분산 트랜잭션 대신 보상 트랜잭션 패턴과 함께 이 패턴을 사용합니다.