当前位置:  开发笔记 > 编程语言 > 正文

Golang:即使数据库关闭,Ping也会第二次成功

如何解决《Golang:即使数据库关闭,Ping也会第二次成功》经验,为你挑选了1个好方法。

我遇到了一个有趣的问题,即即使数据库自第一次尝试以来已被杀死,db.Ping()也不会返回错误.

源代码如下:

import (
    "database/sql"
    "fmt"
    "log"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

type database struct {
    datasource string
    conn       *sql.DB
}

// Connect creates and initialises a Database struct
func (db *database) Connect(server, user, password, DBPort string) error {
    var err error

    db.datasource = fmt.Sprintf("%s:%s@/", user, password)
    db.conn, err = sql.Open(server, db.datasource)
    if err != nil {
        log.Fatal(err)
    }

    err = db.conn.Ping()
    if err != nil {
        db.conn.Close()
        return err
    }

    log.Println("Waiting for 15 seconds, kill the DB")
    <-time.After(15 * time.Second)

    err = db.conn.Ping()
    if err != nil {
        db.conn.Close()
        return err
    }

    log.Println("Second ping successful")

    return nil
}

首先,数据库已启动,因此第一个Ping成功.但是,为了测试,我在那里放了一个延迟.在那15秒内我停止了数据库(sudo service mysql stop),然而,db.Ping()仍然成功.

如果我要执行任何实际的查询(通过db.Query,db.QueryRowdb.Exec),那么sql包将使用Broken Pipe(预期)发生混乱.

难道我做错了什么?

另外:go go go7.1.1 linux/amd64

提前致谢!



1> Kaedys..:

在第一次连接之后,Ping实际上并不ping数据库.这是奇怪的,也是错的,但这就是它的工作方式(直到Go 1.8).如果连接池中存在尚未超时的现有连接,Ping将只是将其从池中删除并将其返回给您,而实际上并不打算检查数据库是否仍然存在.

Kardianos(编写上述链接文档以及Govendor)在1.8中修复了此问题,前提是数据库驱动程序支持它.但是,在此之前,Ping确定数据库是否仍然存在并不可靠.

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有