如果在产生Mysql Server Has Gone Away的时候想重新连接怎么办?@qiang.xue

首先感谢qiang给我们共享了一个这么受用的web框架。

在使用yii的过程中,我遇到了一个问题,大致概述如下:




$user_list = fetch_user_from_db();

foreach($user_list as $user)

{

    send_mail_to_user($user->id);

    update_db_user_mail_status($user->id);

}



mysql wait_timeout配置10秒;

在这个crontab执行的过程中,由于send_mail_to_user调用的外部服务,它返回时间在极少数情况下会有超过10秒的情况。最终导致超过mysql wait_timeout的设置。于是在db层增加一个gone away重连的机制(CDbCommand里面的函数execute和queryInternal中增加了判断),加上以后通过CDbcommand进行的操作成功进行了重连,但是通过activerecord进行的操作还是无效。由于对框架的理解还不是特别深入,所以不知道把这个机制加到什么地方比较好。 :lol:

问题解决了,如有需要的同学可以做一个参考;修改db\CDbConnection.php文件(420行开始):




public function getPdoInstance()

{

    $report_level = error_reporting(0);

    // 如果由于延时操作php与mysql的连接时间操作wait_timeout(10秒),那么数据库重新连接

    try {

        if($this->getServerInfo() === 'MySQL server has gone away')

        {

            $this->_pdo = null;

            $this->open();

        }

    } catch(Exception $e) {

        if(strpos($e->getMessage(), 'gone away') !== false)

        {

            $this->_pdo = null;

            $this->open();

        }

    }

    error_reporting($report_level);

    unset($report_level);

    return $this->_pdo;

}



在getPdoInstance函数里增加了对连接的判断,但是在php版本5.2.x和5.3.x之间会有差异。在5.2.x里如果连接失效直接返回字符串信息"MySql server has gone away",但是在5.3.x里则是抛出异常并且报warning级别的错误。很奇怪为什么会同时抛异常和报错,正因为这个warning错误,所以在错误控制上也增加了一个很小的改动。

这个问题在开发后台 commands 的时候经常会遇到,

建议强哥考虑以下这个问题,从底层支持一下。

与其大家都直接改yii源码,或者自己写一大堆不规范的扩展,

不如将这个问题用标准稳定健壮的办法在框架内直接解决掉。