Ответ
В Golang координацию транзакций в Saga можно реализовать несколькими способами:
-
Choreography (Оркестровка без центрального координатора):
- Сервисы общаются через события (Kafka, RabbitMQ)
- Каждый сервис знает свою часть компенсации
// Пример обработки события
func HandleOrderCreated(event Event) {
if err := ProcessPayment(); err != nil {
Publish(PaymentFailedEvent{...})
} else {
Publish(PaymentSucceededEvent{...})
}
}
-
Orchestration (С центральным координатором):
- Отдельный сервис управляет потоком выполнения
- Хранит состояние саги и вызывает компенсации
type SagaOrchestrator struct {
steps []SagaStep
}
func (s *SagaOrchestrator) Execute() {
for _, step := range s.steps {
if err := step.Execute(); err != nil {
s.Compensate()
break
}
}
}
-
Хранение состояния:
- В БД или Redis для восстановления после сбоев
- Важно обеспечить идемпотентность операций
-
Таймауты:
- Контроль времени выполнения каждого шага
- Автоматическая компенсация при превышении
Для надежности стоит комбинировать несколько подходов, особенно в распределенных системах.