У меня была похожая проблема, и я решил ее, создав собственный класс для подключения к БД, который гарантирует, что подключение будет активным до фактического запроса.
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 перед созданием команды. В случае сбоя проверки связи (соединение было прервано), он пытается восстановить соединение.
Это не помешает отсоединению, но оно автоматически восстановит соединение в случае, если соединение было прервано. Это может быть сложно, если вы используете транзакции - если соединение прерывается в середине транзакции, транзакция будет неявно откатываться БД, а приведенный выше код будет неявно переподключаться, так что вы даже не заметите, что ваша транзакция была откатом в некоторых случаях. точка.
Также я не тестировал его в конфигурации «ведущий-ведомый». Но в моем случае это прекрасно работало (подключение только для чтения к одному серверу), поэтому вы можете использовать его в качестве базы и настроить его для своих нужд с помощью дополнительных проверок транзакций или соединений master / slave.