Heim >Backend-Entwicklung >PHP-Tutorial >So stellen Sie die Verbindung automatisch wieder her, wenn die MySQL-Verbindung unterbrochen wird

So stellen Sie die Verbindung automatisch wieder her, wenn die MySQL-Verbindung unterbrochen wird

jacklove
jackloveOriginal
2018-06-08 23:11:422360Durchsuche

Verwenden Sie PHP als Hintergrundprogramm (z. B. Massen-SMS) und führen Sie PHP im CLI-Modus aus. PHP muss eine Verbindung zu MySQL herstellen, um die Datenbankverarbeitung in einer Schleife durchzuführen.
Wenn die MySQL-Verbindung unterbrochen wird, schlägt die nachfolgende Ausführung der Schleife fehl.

Wir müssen eine Methode entwerfen, die die Verbindung automatisch wiederherstellen kann, wenn die MySQL-Verbindung getrennt wird, damit nachfolgende Programme normal ausgeführt werden können.

1. Testdatentabelle erstellen

CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. Testdaten einfügen

insert into user(name) values('fdipzone'),('xfdipzone'),('terry');mysql> select * from user;
+----+-----------+| id | name      |
+----+-----------+|  1 | fdipzone  |
|  2 | xfdipzone ||  3 | terry     |
+----+-----------+

3. PHP-Datei läuft im Hintergrund

db.php

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }
}?>

test.php

<?phprequire &#39;db.php&#39;;// 数据库设定$config = array(    &#39;host&#39; => 'localhost',    'dbname' => 'user',    'user' => 'root',    'password' => '',    'pconnect' => 0,    'charset' => '');// 循环执行while(true){    // 创建数据连接
    $dbconn = DB::get_conn($config);    // 执行查询
    $sqlstr = 'select * from user where id=?';    $condparam = array(mt_rand(1,3));    $data = DB::query($dbconn, $sqlstr, $condparam);
    print_r($data);    // 延时10秒
    echo 'sleep 10'.PHP_EOL.PHP_EOL;
    sleep(10);
}?>

4. Führen Sie die Schritte

aus php Führen Sie test.php im CLI-Modus aus und führen Sie dann sofort mysql.server stop und mysql.server start aus, um eine Flash-Unterbrechung zu simulieren

mysql.server stopShutting down MySQL
.. SUCCESS! 
mysql.server start
Starting MySQL
 SUCCESS!

Sie können sehen, dass die Datenbank nach der Flash-Unterbrechung nicht erneut verbunden werden kann Nachfolgende Programme können nicht ausgeführt werden.

Array
(
    [0] => Array
        (
            [id] => 3
            [name] => terry
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10...

5. Fügen Sie einen Wiederverbindungsmechanismus hinzu

if(isset(self::$_instance) && !empty(self::$_instance)){    return self::$_instance;
}

Nach einer Flash-Unterbrechung stellt der Aufruf von get_conn keine erneute Verbindung her, sondern verwendet die gespeicherte Verbindung für die Verarbeitung . .

Dies bedeutet tatsächlich, dass bei bestehender Verbindung keine erneute Erstellung einer MySQL-Verbindung erforderlich ist, wodurch die Anzahl der MySQL-Verbindungen verringert wird.

Daher ist es notwendig, den Wert von self::$_instance nach der Unterbrechung zu löschen, damit die Verbindung beim nächsten Mal wieder hergestellt werden kann, ohne die erstellte, aber abgelaufene Datenbankverbindung zu verwenden.

Die Verbesserungsmethode lautet wie folgt:
Fügen Sie die Methode reset_connect hinzu, die aufgerufen wird, wenn ein Fehler auftritt. Wenn der Beurteilungsfehler MySQL-Server ist verschwunden lautet, wird die bestehende Datenbankverbindung gelöscht. Nach dem Löschen wird MySQL beim nächsten Mal wieder verbunden.

Die geänderte PHP-Datei lautet wie folgt:
db.php

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;            self::reset_connect($e->getMessage()); // 出错时调用重置连接
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }    // 重置连接
    public static function reset_connect($err_msg){
        if(strpos($err_msg, 'MySQL server has gone away')!==false){            self::$_instance = null;
        }
    }
}?>

6. Führen Sie die Flash-Ausführung erneut aus

Sie können den verbesserten Effekt sehen. Nach der Unterbrechung schlägt die aktuelle Ausführung fehl, nachfolgende Ausführungen können jedoch neu erstellt werden und eine neue Verbindung wird fortgesetzt.

Array(
    [0] => Array
        (
            [id] => 2
            [name] => xfdipzone
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray(
)
sleep 10Array(
    [0] => Array
        (
            [id] => 1
            [name] => fdipzone
        )
)
sleep 10...

In diesem Artikel werden die relevanten Kenntnisse über die Methode der automatischen Wiederherstellung der Verbindung bei Unterbrechung der MySQL-Verbindung erläutert. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

php implementiert eine Klasse zum Konvertieren von HTML-Entitätsnummern und Nicht-ASCII-Strings

php gemäß Die sich selbst erhöhende ID erstellt eine eindeutige Zahlenklasse

Über MySQL Die Methode zum Anzeigen der aktuell verwendeten Konfigurationsdatei my.cnf wird erklärt

Das obige ist der detaillierte Inhalt vonSo stellen Sie die Verbindung automatisch wieder her, wenn die MySQL-Verbindung unterbrochen wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn