Przejdź do treści
DedicatedPHP Kontakt

Masowe importy w PHP bez utraty kontroli

Projektuj masowe importy w PHP z walidacją, partiami, kwarantanną, idempotencją i selektywnym wznawianiem bez powtarzania całego importu.

Panel importu danych z walidacją według wierszy, przetworzonymi partiami i rekordami w kwarantannie

Masowe importy w PHP często zaczynają się od pliku CSV przesłanego przez klienta, eksportu od dostawcy lub wyciągu z systemu legacy. Ryzyko pojawia się, gdy są traktowane jako zwykłe odczytanie pliku, po którym następują operacje INSERT w bazie danych. Wiersz może mieć prawidłowy format, a mimo to utworzyć duplikat, naruszyć regułę biznesową, nadpisać aktualne informacje lub dwukrotnie wywołać efekt zewnętrzny.

Import należy projektować jako proces operacyjny o określonym cyklu: przyjęcie, analiza, walidacja, podgląd, potwierdzenie, wykonanie, przegląd i odzyskiwanie. Takie podejście pozwala zespołowi produktowemu zrozumieć, co zostanie dodane, zespołowi operacyjnemu reagować w przypadku wyjątków, a zespołowi technicznemu ograniczać wpływ wadliwych danych.

Traktowanie importu jako procesu biznesowego

Traktowanie importu jako procesu biznesowego — guía visual de DedicatedPHP

Plik sam w sobie nie jest źródłem prawdy: jest żądaniem zmiany stanu aplikacji. Dlatego warto utworzyć encję importu z własnym identyfikatorem, użytkownikiem lub systemem, który go zainicjował, datą otrzymania, typem danych, wersją kontraktu, plikiem lub bezpiecznym wskaźnikiem do niego, stanem globalnym i podsumowaniem wyników.

Stany globalne powinny wyrażać sytuację, z którą można operacyjnie pracować, a nie tylko wartość logiczną. Na przykład: otrzymany, przeanalizowany, oczekujący na potwierdzenie, w toku, zakończony, zakończony z problemami, zatrzymany lub anulowany. Import z 9 800 zaakceptowanymi wierszami i 200 odrzuconymi nie musi oznaczać porażki; może być wykonaniem zakończonym z problemami, jeśli odrzucone wiersze są odizolowane i wyjaśnione.

Należy też zdecydować, jakie konsekwencje należą do importu. Utworzenie zamówienia, aktualizacja katalogu lub dodanie kontaktów może wymagać obliczeń, audytu albo powiadomień. Oddzielenie głównej persystencji od efektów ubocznych zmniejsza ryzyko, że ponowna próba wyśle powtarzające się wiadomości lub wykona integracje w niekontrolowany sposób.

Zdefiniowanie kontraktu wejściowego przed zaakceptowaniem plików

Kontrakt importu określa, co ma zostać otrzymane i jak będzie interpretowane. Powinien obejmować dozwolony format, kodowanie, separator, nagłówki, typy danych, pola wymagane, format dat, reguły normalizacji, limity rozmiaru i maksymalną liczbę wierszy. Jeśli akceptowane są arkusze kalkulacyjne, należy również zdefiniować właściwy arkusz oraz sposób traktowania pustych komórek, formuł i wartości automatycznie przekształconych.

Pola łączące źródło z celem zasługują na szczególną uwagę. Stabilny identyfikator zewnętrzny, taki jak kod klienta w systemie źródłowym, jest lepszy niż używanie numeru wiersza lub nazwy jako identyfikatora. Należy wyjaśnić, czy ten identyfikator tworzy rekord, aktualizuje istniejący, czy też obie operacje są dozwolone.

Rozdzielenie warstw walidacji

Walidacja strukturalna odpowiada na pytania mechaniczne: czy plik można odczytać?, czy istnieją wymagane kolumny?, czy data ma dopuszczalny format?, czy kwota jest liczbowa?, czy wiersz spełnia limit długości? Ta warstwa powinna wcześnie wykrywać problemy uniemożliwiające interpretację danych.

Walidacja domenowa stosuje reguły biznesowe: status może być niedozwolony, data zakończenia nie może poprzedzać daty rozpoczęcia, procent musi pozostawać w swoim zakresie albo kombinacja pól może być niezgodna. Na koniec kontrole względem istniejących danych weryfikują odwołania, uprawnienia, unikalność i dozwolone przejścia. Na przykład, czy kod dostawcy istnieje, czy użytkownik może działać na rzecz tej organizacji albo czy rekord nie jest zablokowany.

To rozdzielenie poprawia komunikaty i diagnostykę. Brakująca kolumna to nie to samo co nieistniejące odwołanie lub nieautoryzowana zmiana. Ponadto reguły domenowe powinny być ponownie wykorzystywane przez aplikację i importer, aby import nie stał się skrótem omijającym zwykłe kontrole.

Podgląd zmian i potwierdzenie wyraźnej intencji

Podgląd nie powinien obiecywać dokładnego wykonania, jeśli dane mogą zmienić się między analizą a potwierdzeniem, ale powinien oferować weryfikowalne oszacowanie. Należy pokazać łączną liczbę odczytanych wierszy, wierszy prawidłowych, wierszy z ostrzeżeniami, wierszy odrzuconych, przewidywanych nowych rekordów, przewidywanych aktualizacji i rekordów, które nie ulegną zmianie.

Ostrzeżenia służą przypadkom wymagającym uwagi, lecz nie unieważniają automatycznie wiersza: na przykład znormalizowanemu numerowi telefonu, opisowi skróconemu zgodnie ze znaną regułą lub pustemu polu opcjonalnemu. Ostrzeżenia nie powinny ukrywać odrzuceń. Każdy wynik wymaga stabilnego kodu, zrozumiałego komunikatu oraz, gdy jest to bezpieczne, otrzymanej wartości i wartości znormalizowanej.

Potwierdzenie musi być powiązane z konkretną wersją analizy. Jeśli użytkownik zastąpi plik, poprawi wiersze w interfejsie lub zmieni istotne parametry, system powinien unieważnić poprzedni podgląd i wymagać nowej analizy. Pozwala to uniknąć potwierdzenia podsumowania, które nie przedstawia już rzeczywistego importu.

Przetwarzanie partiami bez niejednoznacznych stanów

Przetwarzanie wszystkich wierszy w ramach jednej transakcji wydaje się bezpieczne, ale może zbyt długo utrzymywać blokady, przekroczyć limity wykonania lub zamienić pojedynczą awarię w kosztowne wycofanie. Z kolei przetwarzanie jednego wiersza na transakcję może generować zbyt duży narzut i utrudniać koordynację powiązanych operacji.

Jednostkę pracy należy dobrać zależnie od zależności między rekordami, wolumenu i kosztu wycofania. W wielu przypadkach mała, ograniczona partia pozwala stopniowo zatwierdzać zmiany. Każda partia powinna rejestrować rozpoczęcie, zakończenie, liczbę obsłużonych wierszy i wynik. Proces przetwarzający musi móc wznowić działanie bez zależności od otwartej sesji HTTP: import jest potwierdzany z interfejsu, lecz wykonywany jako zadanie w tle.

Należy unikać przechowywania całych plików w pamięci. Należy odczytywać je sekwencyjnie, normalizować każdy wiersz i przechowywać reprezentację roboczą lub wynik walidacji, gdy jest to konieczne do audytu i wznowienia. Należy narzucać limity rozmiaru, liczby wierszy, czasu i współbieżności. Nieoczekiwanie duży plik nie powinien blokować zasobów obsługujących codzienną pracę.

dla każdej oczekującej partii:
  oznacz partię jako w_toku
  dla każdego wiersza w partii:
    wykonaj pozostałe kontrole walidacyjne
    zapisz lub wyślij do kwarantanny
    zarejestruj wynik dla wiersza
  zatwierdź partię
  oznacz partię jako zakończoną

Jeśli proces przetwarzający zostanie przerwany, nie wystarczy ponownie uruchomić partii w ciemno. Potrzebny jest mechanizm blokady z wygaśnięciem lub odzyskiwaniem, a stan każdego wiersza musi pozwalać odróżnić elementy oczekujące od już zatwierdzonych.

Izolowanie błędów w kwarantannie i zachowanie dowodów

Kwarantanna pozwala, aby nieprawidłowe wiersze nie blokowały poprawnych, nie znikając przy tym z procesu. Wiersz w kwarantannie powinien zachowywać numer lub identyfikator źródłowy, otrzymane dane objęte kontrolami dostępu, dane znormalizowane, jeśli istnieją, kody błędów, moment wykrycia i stan przeglądu.

Nie wszystkie błędy są traktowane tak samo. Plik bez wymaganego nagłówka jest błędem pliku i może zatrzymać całą analizę. Wskazanie nieistniejącego dostawcy może być odrzuceniem wiersza. Tymczasowa awaria bazy danych lub integracji jest błędem technicznym, który można ponowić, i nie powinna być oznaczana jako wada danych.

Interfejs operacyjny powinien umożliwiać filtrowanie według przyczyny, eksportowanie wyłącznie pozycji nieprawidłowych, których eksport jest autoryzowany, oraz zrozumienie, jakiej korekty się oczekuje. Poprawianie w aplikacji może być przydatne w nielicznych przypadkach; dla wielu rekordów zwykle bardziej kontrolowane jest pobranie pozycji nieprawidłowych, poprawienie ich w źródle i przesłanie nowego importu. W obu przypadkach należy zachować historię: modyfikacja wiersza w kwarantannie nie powinna usuwać pierwotnej wartości ani początkowej przyczyny.

Zapewnienie idempotencji i unikanie duplikatów

Idempotencja oznacza, że powtórzenie operacji z tą samą intencją nie zmienia wyniku więcej niż raz. Jest niezbędna, ponieważ ponowne próby się zdarzają: upływa limit czasu oczekiwania, proces zostaje zrestartowany lub operator potwierdza ponownie po niejednoznacznej odpowiedzi.

Klucz idempotencji można zbudować na podstawie typu importu, organizacji docelowej i stabilnego identyfikatora zewnętrznego. Gdy model na to pozwala, powinien być wsparty ograniczeniami unikalności w bazie danych; sprawdzenie najpierw, a następnie operacja INSERT nie eliminuje warunków wyścigu między równolegle działającymi procesami.

Dla aktualizacji należy zdefiniować wyraźną politykę: zastępowanie pól, stosowanie tylko wartości niepustych, odrzucanie konfliktów lub wymaganie oczekiwanej wersji rekordu. Ostatnia opcja pomaga wykryć, że użytkownik zmienił dane po podglądzie. Nie należy używać odcisku pliku jako jedynego mechanizmu: ta sama zawartość może reprezentować inną intencję, a poprawiony plik może zachować wiele już przetworzonych wierszy.

Śledzalność, ponowne próby i selektywne odzyskiwanie

Śledzalność, ponowne próby i selektywne odzyskiwanie — guía visual de DedicatedPHP

Wynik dla każdego wiersza jest centralnym elementem wsparcia i odzyskiwania. Należy rejestrować stan taki jak oczekujący, przetworzony, odrzucony, w kwarantannie, oczekujący na ponowną próbę lub pominięty; identyfikator zewnętrzny; partię; kody przyczyn; znaczniki czasu; oraz identyfikator utworzonego lub zaktualizowanego rekordu. Należy chronić dane osobowe i sekrety: śledzalność powinna wystarczać do zbadania sprawy, a nie być bezkrytyczną kopią wrażliwych informacji w logach.

Ponowne próby powinny być selektywne. Należy automatycznie ponawiać przejściowe błędy techniczne z limitami i progresywnym oczekiwaniem; nie należy bez końca ponawiać niespełnionej reguły domenowej. Gdy brakujące odwołanie lub nieprawidłowa dana zostanie poprawiona, należy przetworzyć ponownie tylko odpowiadające jej wiersze w kwarantannie. Gdy partia zakończy się błędem, należy kontynuować od oczekujących wierszy i wykorzystywać już przetworzone jako dowód postępu.

Przed wdrożeniem przepływu na produkcję należy przetestować puste pliki, zmienione nagłówki, nieoczekiwane kodowania, duplikaty w tym samym pliku, duplikaty względem bazy danych, przerwania między partiami, wznowienia i niewystarczające uprawnienia. Masowe importy w PHP są niezawodne, gdy ich zachowanie w razie awarii projektuje się z taką samą precyzją jak ich poprawną ścieżkę.

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