Я запускаю консольное приложение Yii2, которое запускает службу чата websocket. Что все работает нормально и как положено, но через некоторое время бездействия я получаю SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
, Я пытался увеличить тайм-ауты, установить для пользователя прерывание на ложь и установить PDO::ATTR_PERSISTENT => true
в PDO
конструктор, но это все еще происходит.
Есть ли способ проверить, является ли соединение с базой данных все еще активным или нет, как восстановить соединение с БД. Либо в чистом php, либо лучше с фреймворком Yii2.
У меня была похожая проблема, и я решил ее, создав собственный класс для соединения с БД, который гарантирует, что соединение будет активным до фактического запроса.
class DbConnection extends \yii\db\Connection {
private $stamp;
/**
* {@inheritdoc}
*/
public function createCommand($sql = null, $params = []) {
try {
// send ping on every 10 seconds
if ($this->stamp < time()) {
$this->stamp = time() + 10;
parent::createCommand('SELECT 1')->execute();
}
} catch (\yii\db\Exception $e) {
// if ping fail, reconnect
$this->close();
$this->open();
}
return parent::createCommand($query);
}
}
Раз в 10 секунд перед отправкой команды отправляется запрос ping. Если ping не удается (соединение было прервано), он пытается восстановить соединение.
Это не помешает отсоединению, но оно автоматически восстановит соединение в случае, если соединение было прервано. Это может быть сложно, если вы используете транзакции — если соединение прерывается в середине транзакции, транзакция будет неявно откатываться БД, а приведенный выше код будет неявно переподключаться, поэтому вы даже не заметите, что ваша транзакция была откатом в некоторый момент времени. точка.
Также я не проверял это в конфигурации master-slave. Но в моем случае это прекрасно работало (подключение только для чтения к одному серверу), поэтому вы можете использовать его в качестве базы и настроить его для своих нужд с помощью дополнительных проверок транзакций или соединений master / slave.
Не уверен, где именно вы должны идти именно для этого кода, но соответствующий код, чтобы проверить, является ли соединение активным, следуя методам в yii\db\Connection
класс может быть использован
getIsActive()
Возвращает значение, указывающее, подключено ли соединение с БД.
Установлено.
и для повторного подключения вы можете использовать
open()
: Устанавливает соединение с БД. Ничего не делает, если БД
соединение уже установлено.
if(Yii::$app->db->isActive === FALSE){
Yii::$app->db->open();
}