2015-01-30 24 views
5

Ho provato diversi tentativi/cicli di acquisizione per tentare di risolvere i problemi automaticamente, ma sembrano sempre causare la morte del software.Riprovare/tentare quando fallisce

$doLoop = true; 

while ($doLoop) { 

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

Ecco il mio originale try/catch.

Il problema è che a volte il server MySQL "va via" e ho bisogno di intercettare quell'eccezione e riprovare fino a quando non ritorna.

Cosa posso modificare qui per ottenere questo per continuare a riprovare fino al successo?

+1

eri abbastanza vicino alla soluzione :) – dynamic

+1

Ti imploro di cercare _why_ il tuo server MySQL "se ne va". Una definizione di follia sta provando la stessa cosa più e più volte mentre si aspettano risultati diversi. – sjagr

+1

Se il tuo db a volte "va via" allora la tua soluzione non dovrebbe essere quella di riprovare in PHP, dovrebbe essere quello di risolvere il problema di connettività. Questo codice è un ciclo infinito in attesa di accadere. –

risposta

10

uso di una pausa, come ultima istruzione nel tuo try blocco di lasciare il ciclo infinito solo in caso di successo:

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); 
} 

È possibile anche limitare il numero di tentativi, utilizzando un ciclo for invece:

// 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); 
} 

Annotare il usleep() chiamata:

Questo è importante perché altrimenti il ​​processo PHP richiederebbe tutte le risorse (100% CPU) mentre riprovò il più velocemente possibile. È possibile regolare il valore in base alle proprie esigenze. (forse 200 ms è troppo lungo o troppo corto nel tuo caso)

Inoltre, potrebbe essere necessario riconnettersi al DB MySQL in caso di errore! Nel mio esempio non ho incluso il codice per quel caso.

2

Ciò funzionerà solo se la funzione insertIntoDb genererà un'eccezione. Se usi le funzioni mysql *, allora non funzionerà.

Dopo insertIntoDb($data); si dovrebbe impostare $doLoop = false

+0

Sto usando PDO per questo. Funzionerà? –

+0

Se stai passando l'eccezione di PDO allora sì. La tua funzione 'insertIntoDb()' non dovrebbe contenere un try-catch – PKeidel

+0

Ok, eccellente. Grazie. –

Problemi correlati