Scenariusz edukacyjny inspirowany praktyką. Zamówienie zostało zapisane, ale informacyjny e-mail nie wyszedł. To nie jest jedna nieudana operacja. To jeden zakończony wynik biznesowy i jeden niespełniony skutek pomocniczy.
Najpierw nazwij wynik
Jeżeli przyjęcie zamówienia kończy się zatwierdzeniem rekordu, ten moment jest granicą wyniku biznesowego. E-mail, SMS, indeks wyszukiwarki czy wpis analityczny mogą być skutkami tego wyniku. Nie wolno pozwolić, by awaria dodatku zmieniła prawdziwe „zamówienie przyjęte” w fałszywe „spróbuj ponownie”. Tak właśnie rodzą się duplikaty.
Asynchroniczność nie oznacza jednak „wyślij coś na kolejkę i miej nadzieję”. Zapis zamówienia oraz publikacja komunikatu to dwa zapisy. Jeżeli proces umrze pomiędzy nimi, zamówienie istnieje, a wiadomości nie ma.
Trwały zamiar wykonania
Najprostszy wariant to rekord oczekującego powiadomienia zapisany w tej samej lokalnej transakcji co zamówienie. Proces roboczy odczytuje rekord, wysyła wiadomość i oznacza wynik. Gdy więcej odbiorców korzysta ze zdarzeń, tę samą zasadę realizuje transactional outbox: zmiana domenowa i wpis do skrzynki wychodzącej powstają atomowo, a osobny relay publikuje wpis dalej.
Outbox zamyka lukę między bazą i brokerem, ale nie czyni systemu magicznie „exactly once”. Relay może opublikować tę samą wiadomość ponownie. Konsument potrzebuje stabilnego identyfikatora operacji oraz idempotencji albo deduplikacji. Dla e-maila warto również ustalić, czy drugi identyczny komunikat jest tolerowany, czy ma być powstrzymany.
Retry jest decyzją, nie odruchem
- ponawiaj tylko zadanie, które się nie udało, a nie całą operację biznesową;
- stosuj ograniczoną liczbę prób, opóźnienie i jitter, aby nie dobić zależności podczas awarii;
- po wyczerpaniu prób zachowaj zadanie do obsługi i uzgodnienia zamiast usuwać ślad;
- mierz wiek najstarszego oczekującego zadania, liczbę prób i odsetek trwałych błędów;
- pokaż użytkownikowi prawdę: zamówienie przyjęto, a potwierdzenie może przyjść później.
Jak sprawdzić decyzję
Testuj trzy awarie: poczta jest niedostępna, proces kończy się po commicie bazy, a relay publikuje komunikat dwukrotnie. Wynik ma być nudny: jedno zamówienie, trwałe zadanie, kontrolowane ponowienie i co najwyżej jedno widoczne powiadomienie. Architektura odporna bywa nudna. To komplement.
Granica zastosowania: jeśli powiadomienie jest prawnym lub biznesowym warunkiem przyjęcia operacji, nie jest skutkiem pomocniczym. Najpierw trzeba ustalić kontrakt, dopiero potem dobierać wzorzec.
Porozmawiajmy o tym artykule
Podziel się uwagą lub zanonimizowanym przykładem. Komentarze sprawdza AI przed publikacją. Niejednoznaczne przypadki trafiają do moderatora.