这篇文章主要介绍了doctrine实现自动重连mysql数据库机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
不知道大家有没有碰到就是mysql有的时候会八小时不使用的话自动断开连接,这样会导致我们的请求失败,项目访问报错,数据库断开,这个时间要是失效了,那我们该怎么办呢?我们使用的是doctrine-dbal,所以那我们就写一套自动重连的机制吧!话不多bb,直接上代码。
<?php
namespace WsdServer\Lib\PDO;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection AS Connection;
/**
* A wrapper around a Doctrine\DBAL\Connection that adds features like
* reconnect
*
*/
class WsdConnection extends Connection
{
const RECONNECT_MAX_TIMES = 3; // 最多重试次数
private $reconnectRetryTimes;
public function __construct(array $params, Driver $driver, Configuration $config = null,
EventManager $eventManager = null)
{
parent::__construct($params, $driver, $config, $eventManager);
}
/**
* executeQuery - 支持自动重连机制的封装
*
* Executes an, optionally parametrized, SQL query.
*
* If the query is parametrized, a prepared statement is used.
* If an SQLLogger is configured, the execution is logged.
*
* @param string $query The SQL query to execute.
* @param array $params The parameters to bind to the query, if any.
* @param array $types The types the previous parameters are in.
* @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp The query cache profile, optional.
*
* @return \Doctrine\DBAL\Driver\Statement The executed statement.
*
* @throws DBALException
* @throws \Exception
*/
public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
{
try {
$result = parent::executeQuery($query, $params, $types, $qcp);
$this->reconnectRetryTimes = 0;
return $result;
} catch (DBALException $dex){
if ( $dex->getErrorCode() == 2006 ) {
if ($this->reconnectRetryTimes <= WsdConnection::RECONNECT_MAX_TIMES) {
$this->reconnectRetryTimes++;
secho("ORM-executeQuery", "MySQL Reconnect...("
. $this->reconnectRetryTimes . "/" . WsdConnection::RECONNECT_MAX_TIMES . ")");
$this->close();
return $this->executeQuery($query, $params, $types, $qcp);
}
}
throw $dex;
} catch (\Exception $ex) {
throw $ex;
}
}
/**
* executeUpdate - 支持自动重连机制的封装
*
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
* and returns the number of affected rows.
*
* This method supports PDO binding types as well as DBAL mapping types.
*
* @param string $query The SQL query.
* @param array $params The query parameters.
* @param array $types The parameter types.
*
* @return integer The number of affected rows.
*
* @throws DBALException
* @throws \Exception
*/
public function executeUpdate($query, array $params = array(), array $types = array())
{
try {
$result = parent::executeUpdate($query, $params, $types);
$this->reconnectRetryTimes = 0;
return $result;
} catch (DBALException $dex){
if ( $dex->getErrorCode() == 2006 ) {
$this->reconnectRetryTimes++;
if ($this->reconnectRetryTimes <= WsdConnection::RECONNECT_MAX_TIMES) {
secho("ORM-executeQuery", "MySQL Reconnect...("
. $this->reconnectRetryTimes . "/" . WsdConnection::RECONNECT_MAX_TIMES . ")");
$this->close();
parent::executeUpdate($query, $params, $types);
}
}
throw $dex;
} catch (\Exception $ex) {
throw $ex;
}
}
}
这样用现在的两个方法覆盖了它原来本身的,这样从连机制简简单单的好了,
测试了一波,发现我们 kill mysql,在重新起来的时候他会自动重新连接,原因是它本身的底层有一个,$this->connect()。所以我们不用怕了