关于数据库断线重连的一点点思考

最近在写数据库链接池,一个不可逃避的问题就是数据库断线重连。 查了很多资料,因为公司有很多项目用了 TP5 于是也去看了它的源码。

tp5的实现其实很简单,配置了一些数据库连接相关的错误信息关键词(句),然后在执行语句时 catch 异常信息进行比对:

// 服务器断线标识字符
    protected $breakMatchStr = [
        'server has gone away',
        'no connection to the server',
        'Lost connection',
        'is dead or not enabled',
        'Error while sending',
        'decryption failed or bad record mac',
        'server closed the connection unexpectedly',
        'SSL connection has been closed unexpectedly',
        'Error writing data to the connection',
        'Resource deadlock avoided',
        'failed with errno',
    ];
catch (\PDOException $e) {
            if ($this->isBreak($e)) {
                return $this->close()->query($sql, $bind, $master, $pdo);
            }
            throw new PDOException($e, $this->config, $this->getLastsql());
        }
protected function isBreak($e): bool
    {
        if (!$this->config['break_reconnect']) {
            return false;
        }
        $error = $e->getMessage();
        foreach ($this->breakMatchStr as $msg) {
            if (false !== stripos($error, $msg)) {
                return true;
            }
        }
        return false;
    }

(噢 突然发现5.2已经开始使用 php7新特性了)

感觉用 errMessage 没有 errCode 靠谱吧,但是用 errCode 也很头疼啊,我要搜集各种数据库的连接相关的错误码,tp5自带的那些错误信息也只是 mysql 的吧,至少没看见sqlserver 的“TCP Provider: Error code 0x2746”,我的连接池是想支持多种数据库的。。。

正在头疼的时候,突然灵光一现:

从连接池取出db连接对象时,先执行一句类似“select 1”这样的非常简单、不会有语法错误、与业务无关(表无关、字段无关。。。) 的语句,如果报错则理论上证明即使不是连接问题 它也已经不能正常执行业务SQL了,再加一个重连次数限制,防止特殊情况下有可能发生的死循环。。。应该就完美了。。。

/**
     * 检查 db连接对象 是否可用, 主要针对断线重连
     * @param $dbKey
     * @return bool
     */
    static private function _check($dbKey)
    {
        try {
            self::$dbUsing[$dbKey]->check();
        } catch (\Exception $e) {
            return false;
        }
        return true;
    }
function check(){
        $this->prepare('select 1');
        return $this->execute();
    }

还有一种思路是做“心跳”检查,定时把连接池里的对象“请”出来“遛”一下,使其保持“活力”。。。但是这个和断线重连并不冲突,可以叠加使用,效果更好。。。


另:在测试中发现,mysql 好像可以自动重连具体表现为:在一个断开的 pdo连接对象执行第一句sql 时 catch 了异常并让代码继续执行,则后面的 sql 就可以执行成功。

我在网上没有查到这一行为相关资料,所以不确定它与 pdo 有关或是 mysql 的功能 又是否跟mysql版本有关。。。

转载于:https://my.oschina.net/u/2399303/blog/1939668

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值