Quando mysql's wait_timeout è stato superato, perdo la connessione sul mio script PHP CLI. Non riesco a cambiare wait_timeout, quindi come si costruisce una dichiarazione try/catch che si riconnette quando uso PDOStatement per eseguire le mie query?PDO con PDOStatement ricollega su "mysql server gone" error
risposta
L'approccio migliore è quello di avvolgere la creazione dell'istanza DOP in un Singleton (cioè MyPDOFactory) che memorizza sia l'istanza e il tempo della creazione, in questo modo, è possibile riutilizzare o ricrearla dopo un TTL è stato raggiunto (2 o 3 secondi è più che sufficiente per la maggior parte delle applicazioni). Dovrai semplicemente chiamare MyPDOFactory :: get() per ottenere un PDO valido che puoi utilizzare per preparare il PDOStatement, ma assicurati di eseguirlo il prima possibile.
penso che questo possa aiutarti.
/* Your Database Name */
$dbname = 'mydatabase';
/* Your Database User Name and Passowrd */
$username = 'root';
$password = 'password';
try {
/* Establish the database connection */
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* your code goes here*/
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
//mysql_close($conn);
$conn=null;
La tua risposta è inutile per riconnettersi dopo il timeout. Nel blocco try è necessario inserire il codice della query e, se la connessione è andata, ricollegarsi nel blocco catch. E poi in qualche modo lanciare nuovamente la query ... –
riconnessione ad un DB dopo un errore è in realtà un problema molto più complicato di quanto non sarebbe sembrare a prima vista.
mia prima idea era di scrivere una semplice classe wrapper per PDO che proxy metodi su un oggetto PDO interno e può gestire connessioni errori si:
class BetterPDO extends PDO
{
private $realPDO = NULL;
private $dsn = "";
private $username = "";
private $password = "";
private $options = [];
public function __construct ($dsn, $username = "", $password = "", $options = [])
{
$this -> dsn = $dsn;
$this -> username = $username;
$this -> password = $password;
$this -> options = $options;
}
private function getRealPDO()
{
if (is_null ($this -> realPDO))
{
$this -> realPDO = new PDO ($this -> dsn, $this -> username, $this -> password, $this -> options);
}
return $this -> realPDO;
}
// We're only implementing exec for brevity but you have to do this for all public methods of PDO
public function exec ($sql)
{
$retries = 0;
while (true)
{
try
{
return $this -> getRealPDO() -> exec ($sql);
}
catch (PDOException $ex)
{
$this -> realPDO = NULL;
if (++$retries > 5)
{
// We've passed our retry limit
throw $ex;
}
}
}
}
}
Poiché questa classe estende DOP, può essere utilizzato ovunque la può essere usata una classe generica DOP.
Come si può vedere, questo approccio vi darà un paio di tentativi prima che il metodo exec() si arrende, che permette la riconnessione dopo errori transitori (questo è solo per la dimostrazione e manca di alcune funzionalità di una reale implementazione avrebbe bisogno, come un backoff tra tentativi, adeguata registrazione degli errori, ecc.). Questo approccio richiede anche che tu controlli le specifiche dell'eccezione PDO generata in base al fatto che non vuoi che cose come gli errori di sintassi MySQL causino il reset della connessione e un tentativo di nuovo tentativo. Vuoi solo che accada su cose come "Il server è andato via".
Come si può anche vedere, l'implementazione di tutti i metodi PDO proxy diventerebbe un lavoro ingrato, anche se come si deve fare solo una volta è probabilmente la pena investire lo sforzo per farlo.
C'è un problema molto più grande, che è praticamente un problema universale per qualsiasi codice che parla con un database, non solo PDO. Cosa succede se una connessione viene persa nel mezzo di una transazione? Non vuoi che il tuo script si ricolleghi e riprenda da dove era stato interrotto in quel caso, perché tutto il lavoro che hai svolto fino all'ultimo commit sarebbe andato perduto, e le probabilità sono che non avrebbe senso riprendere logicamente dopo aver ricollegato, dovresti ricominciare da capo. Quindi probabilmente vorrai ricominciare da capo l'intero script e tentare una riconnessione non avrebbe alcun senso. Questo è probabilmente il motivo per cui mySQLI supporta la riconnessione ma PDO no.
Se lo script fa solo legge o scrive non di transazione, quindi l'approccio di cui sopra ha ancora un valore, ma non appena si lancia transazioni nel mix si sta effettivamente molto meglio non tentare di riconnettersi.
- 1. PHP5 Eccezione MySql e PDO
- 2. PHP MySQL PDO lastInsertID causa l'errore irreversibile
- 3. PDOStatement to json
- 4. PDO e MySQL "tra"
- 5. PDO in prestazioni mysql
- 6. MySQL versus PDO
- 7. Non è possibile connettersi al server MySQL tramite PDO
- 8. PDOstatement (MySQL): inserendo il valore 0 in un campo bit (1) risulta 1 scritto nella tabella
- 9. mysql error 'TYPE = MyISAM'
- 10. layout Android con visibilità GONE
- 11. PDO Inserisce i dati due volte su una singola query
- 12. MySQL e PDO: Potrebbe il PDO :: lastInsertId fallire teoricamente?
- 13. Come posso connettermi a MySQL su un server WAMP?
- 14. Internal Server Error
- 15. Error 403. Wamp Server
- 16. Internal Server Error - .htaccess
- 17. Come ottenere tipi numerici da MySQL usando PDO?
- 18. Come eseguire script mysql con variabili usando PHP :: PDO?
- 19. restituisce un valore dal database con mysql php pdo
- 20. Procedura memorizzata MySQL su una replica di lettura con PDO PHP
- 21. Internal Server Error con web.config IPSecurity
- 22. Installazione PHP PDO su Windows (xampp)
- 23. Impossibile installare PDO su CentOS
- 24. SQL Server errore 1934 si verifica su INSERT alla tabella con la colonna calcolata PHP/PDO
- 25. Istruzione preparata PHP PDO - query MySQL LIKE
- 26. VS2010 ricollega sempre il progetto
- 27. query parametrica preparata con PDO
- 28. Errore HY093 con una richiesta di inserimento PDO MySQL
- 29. Esistono buoni tutorial su come utilizzare PDO?
- 30. Configurazione del server MySQL per evitare "MySQL Server è andato via" errore
Capisco la tua idea, ma dovresti davvero aggiungere codice alla tua risposta. –
Cosa succede se stai eseguendo una serie di query che sono a) transazionali, eb) accade più tempo del TTL? – GordonM