美文网首页
Yii2实现mysql断线重连[转载]

Yii2实现mysql断线重连[转载]

作者: willeny | 来源:发表于2018-12-10 14:29 被阅读0次

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

原文链接:https://www.yiichina.com/topic/7296

Yii2实现数据库断线重连

一、前话
在工作中,有时候一些后台脚本需要长时间的运行,同时可能在连接数据库后,长时间不与数据库服务端交互。此时,服务器可能会断开与客户端的连接。从而客户端再次交互时就会出现"MySQL server has gone away"连接丢失。
此次修改达到的效果:断线重连机制对应用层完全透明,无需自己重复发送请求。

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

<?php
    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里修改

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

相关文章

  • Yii2实现mysql断线重连[转载]

    最近遇到“Yii2实现mysql断线重连”问题,找了好久资料,最后找到这篇文档是说明了该情况的,感谢这位作者的分享...

  • yii和yii2连接mysql以及oracle

    yii连接mysql yii连接oracle yii2连接mysql yii2连接oracle

  • 状态同步的断线重连

    最近陆陆续续在给游戏做断线重连相关的工作,大厅服的断线重连问题不是很大,难点主要在于战斗中的断线重连。断线重连要解...

  • 断线重连问题综述

    断线重连主要涉及到几个问题: 判定断线 怎么重连 重连后如何还原游戏环境 判定断线有两种方式,(1)是超时判定断线...

  • 树莓派Wi-Fi断线重连

    实现 WiFi 断线自动重连。原理是用 Python 监测网络是否断线,如果断线则重启网络服务。 配置无线网连接 ...

  • 断线重连

    今天看了下之前游戏登录相关逻辑,重新整理下断线重连的一些做法。 首先,介绍下断线的几种常见情况:情况一:客户端网络...

  • 断线重连

    using System; using System.Collections; using System.Coll...

  • python records断线自动重连mysql

    mysql数据库默认8个小时会断开连接,对于不经常读写mysql的服务来说,很容易被断开。 可以在创建连接对象的时...

  • Webscoket 断线重连

  • 定时断线重连

    客户端断线重连机制。客户端数量多,且需要传递的数据量级较大。可以周期性的发送数据的时候,使用。要求对数据的即时性不...

网友评论

      本文标题:Yii2实现mysql断线重连[转载]

      本文链接:https://www.haomeiwen.com/subject/bmmrhqtx.html