Klasyczne środowisko informatyczne jest silnie przywiązane do transakcji. Transakcja jest piękna. Mówiąc górnolotnie, transakcja przenosi system z jednego stabilnego stanu w drugi także stabilny. Cokolwiek by się nie udało w trakcie jej trwania, daje nam gwarancję, że wszystkie zmiany się wycofają i system pozostaje w stanie spójnym. Stosowanie transakcji jest ogromnie wygodne dla programistów, głównie poprzez to, że łatwo się myśli i pisze kod. Jak łatwo się domyślić, skutkiem powyższego jest nadużywanie transakcji. Nagminnie robi się je za długie. Za długie w dwóch głównych wymiarach
- W wymiarze ilości iteracji, w którym zamiast schematu „jeden item jedna krótka transakcja”, robi się schemat „wiele itemów jedna długa transakcja” np. import 1000 pozycji paragonu w jednej długiej transakcji.
- A także w wymiarze łączenia różnych kontekstów w jedną długą transakcję np. dodanie paragonu, jego zaksięgowanie i przesłanie do rozrachunków w jednej złożonej transakcji.
O ile w pierwszym przypadku rozwiązanie problemu, lub jego nie powodowanie jest dosyć proste, o tyle w drugim przypadku jest znacznie trudniej. Rozważmy taką dużą transakcję w klasycznym systemie

Pierwsza metoda znana jest pod nazwą znacznikowania. Polega ona na tym, że dodajemy kolumnę w dokumencie która oznacza stan jego przetwarzania, po czym cały kod przenosimy do kontekstu nietransakcyjnego, a każdą z operacji umieszczamy w transakcji z jednoczesną zmianą statusu dokumentu, mniej więcej tak
Mamy trzy osobne, małe transakcje, każda działa w osobnym kontekście. Co ważne, po każdej system pozostaje w stanie stabilnym. Gdyby nie udało się dodać dokumentu do rozliczeń, nic złego się nie dzieje, dokument to „wie” bo ma znacznik statusu równy „Zaksięgowany” a nie „Gotowy”. Dalsze procesy biznesowe będą także „wiedzieć”, że taki dokument nie może być dalej przetwarzany (chyba, że uznają, że może). Powtórne uruchomienie całego procesu pominie dwa pierwsze etapy (patrząc na status) i spróbuje wykonać ostatnią transakcję. Proste i skuteczne. Ale! Co prawda nie mamy już dużej transakcji, ale mamy kod, nazwijmy go sterującym, który steruje transakcjami z bardzo różnych kontekstów. Z różnych względów możemy mieć pokusę aby pozbyć się także tej niezręczności.
Jedną z metod na pełne rozdzielenie techniczne i kontekstowe transakcji, jest wprowadzenie architektury zdarzeniowej. Każda „mała” transakcja oprócz swojej pracy rozgłasza jeszcze informację, że tą pracę wykonała. Każdy kontekst nasłuchuje interesujących go komunikatów i jak je otrzyma wykonuję swoją transakcję. Modelowo wygląda to tak


Ja od siebie dodam, że kiedyś dawno temu brałem udział w tworzeniu systemu opartego na zdarzeniach. Pisałem wtedy tak
create trigger biu_books after update on books
as
begin
if (new.price <> old.price)then begin
// … do something in my module
end
end
Czy mi się to sprawdziło? Do pewnych zastosowań tak. Ale nadużywanie tego mechanizmu wpędziło system i twórców w niemałe kłopoty. Podsumowując, skracanie transakcji w każdym wymiarze, (do rozmiarów uzasadnionych) jest bardzo potrzebne. Metod jest wiele i należy zawsze dobierać odpowiednią metodę do wymagań i potrzeb.

Krzysztof Olszewski
Dyrektor Technologii i Architektury Oprogramowania

Krzysztof Olszewski
Dyrektor Technologii i Architektury Oprogramowania
