Przejdź do treści
DedicatedPHP Kontakt

Jak projektować transakcje wsadowe w importach PHP

Dowiedz się, jak wybierać granice transakcji, zapisywać checkpointy i wznawiać importy PHP bez duplikowania zmian ani ukrywania błędów częściowych.

Schemat importu PHP podzielonego na wsady z transakcjami, checkpointami i odzyskiwaniem po błędach

Rozbudowany import może zakończyć się niepowodzeniem z powodu przerwanego połączenia, nieprawidłowych danych lub limitu czasu procesu. Jeśli wszystkie zmiany zależą od jednej transakcji, system może zbyt długo utrzymywać blokady i utracić całą pracę, która została zatwierdzona dopiero na końcu. Jeśli natomiast każdy wiersz jest zapisywany niezależnie, bez planu odzyskiwania, przerwanie może pozostawić niespójne dane.

Projektowanie transakcji wsadowych w importach PHP polega na wyborze jednostek pracy, które można bezpiecznie zatwierdzać, rejestrować i ponawiać. Nie oznacza to, że cały import jest atomowy: zazwyczaj każdy wsad jest atomowy osobno, a cały proces może zostać zastosowany tylko częściowo. To rozróżnienie powinno być widoczne zarówno w implementacji, jak i w obsłudze operacyjnej.

Dlaczego jedna transakcja może być nieodpowiednia

Dlaczego jedna transakcja może być nieodpowiednia — guía visual de DedicatedPHP

Długa transakcja może utrzymywać blokady, zwiększać obciążenie dziennika transakcji i konkurować z zapytaniami aplikacji. Jeśli import przetwarza miliony wierszy, trudno też ocenić, ile pracy pozostało i co zrobić po awarii. Dokładne zachowanie zależy od silnika bazy danych, poziomu izolacji i liczby zapisów, dlatego warto je zmierzyć w rzeczywistym środowisku.

Zatwierdzanie każdego wiersza skraca czas trwania pojedynczej transakcji, ale może zwielokrotnić koszt zatwierdzeń i pozostawić częściowo zastosowane zależności między wierszami. Wsad stanowi rozwiązanie pośrednie: jeśli operacja w grupie zakończy się niepowodzeniem, a wyjątek zostanie przekazany dalej, ta grupa zostanie wycofana; wcześniejsze zatwierdzone wsady pozostaną bez zmian. Aplikacja powinna przedstawiać ten stan jako częściowy postęp, a nie jako pełny sukces ani całkowity rollback.

Wybór odpowiedniej granicy transakcji

Jednostka pracy nie musi zawsze obejmować stałej liczby wierszy. Powinna reprezentować zmiany, które można spójnie zweryfikować i zapisać. Jeśli każdy rekord jest niezależny, wystarczający może być wsad wierszy. Jeśli kilka rekordów tworzy encję biznesową — na przykład nagłówek i jego pozycje — umieszczenie całego zestawu w tej samej transakcji zapobiega zapisaniu niekompletnej encji.

Aby dobrać rozmiar wsadu, oceń czas jego przetwarzania, zużycie pamięci, rywalizację o współdzielone tabele, częstotliwość błędów i koszt ponownego wykonania pracy. Duży wsad zmniejsza liczbę zatwierdzeń, ale przetwarza się dłużej i zwiększa ilość pracy do powtórzenia w razie awarii. Mały wsad ogranicza ten koszt, ale zwiększa narzut i może obniżyć wydajność. Nie ma uniwersalnego rozmiaru: zacznij od konfigurowalnej wartości i dostosuj ją na podstawie reprezentatywnych testów obciążeniowych.

W PHP unikaj wczytywania całego pliku do pamięci, jeśli można go przetwarzać przyrostowo. Odczytaj ograniczoną grupę wierszy, zweryfikuj ich pola, rozpocznij transakcję, wykonaj zapisy i zatwierdź. W razie błędu wycofaj transakcję wsadu i sklasyfikuj problem. Na przykład w PDO kontrolę można wyrazić za pomocą beginTransaction(), commit() i rollBack(); obsługa wyjątków powinna zagwarantować, że nie zostanie podjęta próba zatwierdzenia nieudanej transakcji.

Rejestrowanie postępu w celu niezawodnego wznowienia

Checkpoint wskazuje, która część źródła została przetworzona i zatwierdzona. Może to być stabilny identyfikator, pozycja w pliku lub klucz złożony, o ile umożliwia kontynuowanie bez polegania na zmieniającej się kolejności. W przypadku stronicowanego zapytania bezpieczniej jest zwykle przechodzić według stabilnego klucza niż używać przesunięcia, które może się zmienić, jeśli podczas procesu zostaną wstawione lub usunięte rekordy.

Postęp i zmiany w ramach wsadu powinny być skoordynowane. Jeśli to możliwe, zapisz zmiany biznesowe i nowy checkpoint w tej samej transakcji. Dzięki temu, jeśli proces zakończy się przed zatwierdzeniem, nie zostanie zarejestrowany postęp, którego baza danych nie zastosowała; jeśli transakcja zostanie zatwierdzona, kursor również zostanie przesunięty. Jeśli stan wykonania znajduje się w innym systemie, taka automatyczna atomowość nie istnieje: trzeba zaprojektować uzgadnianie stanu albo zaakceptować ponowne przetwarzanie wsadów i zapewnić im idempotentność.

Zapisuj także identyfikator importu, jego stan, checkpoint, liczniki oraz, w razie potrzeby, odwołanie do wersji lub sumy kontrolnej pliku. Przy wznawianiu sprawdź, czy chodzi o to samo wejście i czy wykonanie można odzyskać. Zdefiniuj jawne stany, takie jak oczekujący, w toku, zakończony i nieudany, a także zasady wykrywania porzuconych wykonań. Nie oznaczaj importu jako zakończonego tylko dlatego, że proces zakończył się bez wyjątku: sprawdź, czy osiągnięto oczekiwany koniec.

Izolowanie błędów i kontrolowanie ponowień

Z góry zdecyduj, czy nieprawidłowy rekord powinien zatrzymać całość, zostać pominięty czy oznaczony do weryfikacji. W przypadku przewidywalnych błędów formatu przydatna może być walidacja przed otwarciem transakcji oraz zapisanie przyczyny wraz z identyfikatorem wiersza. W przypadku błędów zapisu wycofaj dany wsad. Kontynuowanie pracy z kolejnymi wsadami ma sens tylko wtedy, gdy ich dane są niezależne, a import można jednoznacznie oznaczyć jako częściowy.

Rozróżniaj błędy trwałe — takie jak brak wymaganej wartości — od przejściowych, na przykład możliwego do odzyskania przerwania połączenia. Ponawianie próby po błędzie trwałym marnuje zasoby i utrudnia diagnozę. Z kolei ponowienie po błędzie przejściowym może wykorzystywać ograniczoną liczbę prób i wydłużające się odstępy między nimi. Jeśli limit zostanie wyczerpany, zachowaj wystarczający stan i kontekst, by zbadać problem i wznowić pracę bez ukrywania pierwotnej przyczyny.

Ponowienia mogą powodować powtórne zapisy, jeśli nie zostaną starannie zaprojektowane. Używaj kluczy biznesowych lub identyfikatorów źródłowych, aby rozpoznawać już zaimportowane rekordy, i zdecyduj, czy powtórzenie ma wstawiać, aktualizować, ignorować rekord czy sygnalizować konflikt. Ograniczenia unikalności w bazie danych mogą wzmacniać tę decyzję, ale nie zastępują logiki biznesowej. Nie traktuj checkpointu jako jedynego mechanizmu zapobiegania duplikatom: może być nieaktualny albo nie obejmować zmian wprowadzonych inną drogą.

Jeśli wsad wysyła również wiadomości e-mail, publikuje komunikaty lub wywołuje API, transakcja bazy danych nie może cofnąć tych efektów zewnętrznych. Nie wykonuj ich tak, jakby należały do nieistniejącej transakcji rozproszonej. Jedną z możliwości jest zapisanie oczekującego zdarzenia w transakcyjnej tabeli outbox, a następnie jego przetworzenie z ponowieniami i idempotentnymi identyfikatorami. Jeśli operacja zewnętrzna zakończy się niepowodzeniem, stan powinien umożliwić jej odzyskanie bez duplikowania operacji ani twierdzenia, że wsad został w pełni zakończony.

Testowanie spójności, postępu i odzyskiwania

Testy powinny obejmować więcej niż tylko poprawną ścieżkę wykonania. Wstrzykuj awarie przed rozpoczęciem transakcji, podczas zapisów, tuż przed zatwierdzeniem oraz po zatwierdzeniu, ale przed aktualizacją jakiegokolwiek stanu zewnętrznego. Sprawdzaj, które dane pozostają, jaki checkpoint jest zachowany i czy wznowienie daje oczekiwany rezultat. Uwzględnij zduplikowane rekordy, nieprawidłowe wiersze, puste wsady i błędy zapisu.

W reprezentatywnym teście mierz czas przetwarzania wsadu, pamięć, odsetek błędów, czas blokowania i postęp. Sprawdź również, czy liczniki rozróżniają wiersze odczytane, zaakceptowane, odrzucone i zatwierdzone; pojęcie „przetworzone” może być niejednoznaczne, jeśli obejmuje wycofane zmiany. Metryki i logi powinny identyfikować import i wsad, nie ujawniając przy tym wrażliwych danych, które nie są potrzebne do diagnozy.

Lista kontrolna przed wdrożeniem produkcyjnym

Lista kontrolna przed wdrożeniem produkcyjnym — guía visual de DedicatedPHP
  • Jednostka transakcyjna odpowiada spójnej jednostce biznesowej.
  • Rozmiar wsadu można skonfigurować i oceniono go na reprezentatywnych danych oraz przy reprezentatywnym obciążeniu.
  • Checkpoint jest przesuwany dopiero po zatwierdzeniu odpowiedniego wsadu.
  • Strategia wznawiania używa stabilnego klucza i rozpoznaje źródło danych wejściowych.
  • Błędy trwałe i przejściowe są obsługiwane w odmienny, możliwy do zaobserwowania sposób.
  • Powtarzane operacje są idempotentne albo jawnie wykrywają konflikty.
  • Efekty zewnętrzne są przetwarzane za pomocą niezależnej strategii umożliwiającej odzyskiwanie.
  • Testy weryfikują awarie w różnych punktach, a nie tylko pełne wykonanie.

Celem nie jest zapobieżenie każdej awarii, lecz ograniczenie jej skutków i jawne określenie stanu końcowego. Dzięki przemyślanym granicom transakcji, spójnym checkpointom i bezpiecznym ponowieniom import PHP może zostać wznowiony bez mylenia częściowego postępu z zakończeniem i bez ponownego stosowania już zatwierdzonych zmian.

Chcesz zastosować te pomysły w swoim projekcie?Omówmy Twoją platformę PHP.
Zobacz powiązaną usługę