2015-01-30 24 views
5

Wypróbowałem kilka różnych pętli try/catch, aby spróbować rozwiązać problemy automatycznie, ale zawsze wydają się powodować śmierć oprogramowania.Spróbuj ponownie/złap, gdy się zawiedzie

$doLoop = true; 

while ($doLoop) { 

    try { 
     //do a thing 
     insertIntoDb($data); 
    } catch (Exception $e) { 
     //try again 
     insertIntoDb($data); 
     //write error to file 
     writeError($e); 
    } 
} 

Oto mój oryginalny try/catch.

Kwestia jest czasami serwer MySQL "odchodzi" i muszę złapać ten wyjątek i kontynuować ponawianie aż do powrotu.

Co mogę tu zmienić, aby kontynuować próbę, aż do skutku?

+1

byłeś bardzo blisko rozwiązania :) – dynamic

+1

Prosiłbym, abyś spojrzał na "dlaczego twój serwer MySQL" znika. " Jedna z definicji szaleństwa próbuje tego samego w kółko, oczekując różnych rezultatów. – sjagr

+1

Jeśli twoja db czasami "odchodzi", to twoim rozwiązaniem nie powinno być powtarzanie się w PHP, powinno to naprawić problem z łącznością. Ten kod to nieskończona pętla, która czeka, aby się wydarzyć. –

Odpowiedz

10

wykorzystania przerwy jako ostatniego oświadczenia w bloku try opuścić nieskończoną pętlę tylko na sukces:

while (true) { 
    try { 
     //do a thing 
     insertIntoDb($data); 
     break; 
    } 
    catch (Exception $e) { 
     writeError($e); 
    } 
    // sleep 200ms to give the MySQL server time to come back up 
    usleep(200000); 
} 

Można również ograniczyć liczbę prób za pomocą for pętla zamiast:

// do 3 retries before aborting finally 
for ($i=1; $i <= 3; $i++) { 
    try { 
     //do a thing 
     insertIntoDb($data); 
     break; 
    } 
    catch (Exception $e) { 
     writeError($e); 
    } 
    // sleep 200ms to give the MySQL server time to come back up 
    usleep(200000); 
} 

Zanotuj usleep() wezwanie:

Jest to ważne, ponieważ w przeciwnym razie proces PHP zajmowałby wszystkie zasoby (procesor 100%), podczas gdy ponowna próba była tak szybka, jak to tylko możliwe. Możesz dostosować wartość do swoich potrzeb. (może 200ms jest zbyt długi lub zbyt krótki w twoim przypadku)

Pamiętaj też, że po awarii może być konieczne ponowne połączenie z bazą danych MySQL DB! W moim przykładzie nie uwzględniłem kodu dla tej sprawy.

2

To zadziała tylko wtedy, gdy funkcja insertIntoDb wygeneruje wyjątek. Jeśli użyjesz funkcji mysql *, to nie zadziała.

Po insertIntoDb($data); należy ustawić $doLoop = false

+0

Używam do tego celu PDO. Czy to będzie działało? –

+0

Jeśli przekazujesz wyjątek PDO, to tak. Twoja funkcja 'insertIntoDb()' nie powinna zawierać try-catch – PKeidel

+0

OK, doskonała. Dziękuję Ci. –

Powiązane problemy