yii2 mysql预处理_Yii2实现mysql断线重连[转载]

这篇博客介绍了如何在Yii2框架中处理数据库断线重连问题,通过重写`yiidbCommand`类的`execute`和`queryInternal`方法,当出现'MySQL server has gone away'错误时,自动触发断线重连,确保应用层透明。
摘要由CSDN通过智能技术生成

最近遇到“Yii2实现mysql断线重连”问题,找了好久资料,最后找到这篇文档是说明了该情况的,感谢这位作者的分享,记录下来,必备以后查阅。

Yii2实现数据库断线重连

一、前话

在工作中,有时候一些后台脚本需要长时间的运行,同时可能在连接数据库后,长时间不与数据库服务端交互。此时,服务器可能会断开与客户端的连接。从而客户端再次交互时就会出现"MySQL server has gone away"连接丢失。

此次修改达到的效果:断线重连机制对应用层完全透明,无需自己重复发送请求。

正题

一、重写\yii\db\Command类中的execute 与 queryInternal方法

namespace common\components;

use Yii;

/**

* 新增加执行sql时断开重连

* 数据库连接断开异常

* errorInfo = [''HY000',2006,'错误信息']

* Class Command

* @package common\components

*/

class Command extends \yii\db\Command

{

const EVENT_DISCONNECT = 'disconnect';

/**

* 处理修改类型sql的断线重连问题

* @return int

* @throws \Exception

* @throws \yii\db\Exception

*/

public function execute()

{

try{

return parent::execute();

}catch(\Exception $e){

if($this->handleException($e))

return parent::execute();

throw $e;

}

}

/**

* 处理查询类sql断线重连问题

* @param string $method

* @param null $fetchMode

* @return mixed

* @throws \Exception

* @throws \yii\db\Exception

*/

protected function queryInternal($method, $fetchMode = null)

{

try{

return parent::queryInternal($method, $fetchMode);

}catch(\Exception $e){

if($this->handleException($e))

return parent::queryInternal($method, $fetchMode);

throw $e;

}

}

/**

* 处理执行sql时捕获的异常信息

* 并且根据异常信息来决定是否需要重新连接数据库

* @param \Exception $e

* @return bool true: 需要重新执行sql false: 不需要重新执行sql

*/

private function handleException(\Exception $e)

{

//如果不是yii\db\Exception异常抛出该异常或者不是MySQL server has gone away

$offset = stripos($e->getMessage(),'MySQL server has gone away');

if(($e instanceof \yii\db\Exception) == false OR $offset === false)

//OR $e->errorInfo[0] != 'HY000' OR $e->errorInfo[1] != 2006)

return false;

$this->trigger(static::EVENT_DISCONNECT);

//将pdo设置从null

$this->pdoStatement = NULL;

//$this->db->resetPdo();

$this->db->close();

return true;

}

}

使用在common/config/main-local.php里修改

return [

'components' => [

'db' => [

'class' => 'yii\db\Connection',

'commandClass' => 'common\components\Command',// 加上这一条配置,Yii2 解决2006 MySQL server has gone away问题

'username' => 'XXX',

'password' => 'XXX',

'dsn' => 'mysql:host=XXX;dbname=XXX;port=3306',

],

],

];

修改中遇到的问题:

眼尖的同学可能已经看到了在上面的"handleException"函数中有段注释了的代码"OR

math?formula=e-%3EerrorInfo%5B0%5D%20!%3D%20'HY000'%20ORe->errorInfo[1] != 2006" 被"

math?formula=offset%20%3D%20stripos(e->getMessage(),'MySQL server has gone away');" 代替了。那是因为在断线的情况下,客户端首次请求时会产生一个"Error"与一个"PDOException"。由于Yii2在底层实现了一个错误处理函数。在捕获到错误后会转换成一个"ErrorException"导致"PDOException"被覆盖了。同时在"PDOException"中的错误状态码也获取不到了。如果你有更好的方案也希望您能在下面的留言中一起交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值