12
votes

PDO avec la réaccord de pdoStatement sur "MySQL Server Gone" Erreur

Lorsque MYSQL's WAIT_TIMEOUT a été dépassé, je perds la connexion sur mon script php CLI. Je ne peux pas changer wait_timeout, alors comment créer une instruction Essaye / Catch qui reconnecte quand j'utilise une pdostatement pour exécuter mes requêtes?


0 commentaires

3 Réponses :


2
votes

La meilleure approche consiste à envelopper la création d'instances PDO dans un singleton (c.-à-d. Mypdofactory) qui stocke à la fois l'instance et l'heure de la création, de cette façon, vous pouvez la réutiliser ou le recréer après que le TTL ait été atteint (2 ou 3 secondes est plus que suffisante pour la plupart des applications). Vous devrez juste appeler mypdofactory :: get () Pour obtenir un PDO valide que vous pouvez utiliser pour préparer la pdostatement, assurez-vous de l'exécuter dès que possible.


2 commentaires

Je comprends votre idée, mais vous devriez vraiment ajouter du code à votre réponse.


Que se passe-t-il si vous exécutez un ensemble de requêtes qui sont a) transactionnelles, et b) prennent plus de temps que la TTL?



-2
votes

Je pense que cela peut vous aider.

/* 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;


1 commentaires

Votre réponse est inutile pour la reconnexion après l'heure. En essayez que vous devez mettre le code de requête et si la connexion est disparue, reconnectez-vous dans le bloc de capture. Et puis de lancer une question de nouveau ...



4
votes

Reconnexion à un DB après une erreur est en réalité un problème beaucoup plus compliqué que ce serait d'abord.

Ma première idée était d'écrire une classe d'enveloppe simple pour PDO qui proxy Méthodes sur un objet PDO interne et peut gérer les erreurs de raccordement elles-mêmes: P>

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


1 commentaires

Il est également possible d'implémenter la méthode magique __Call dans la classe PDO proxiée