我遇到了一个有趣的问题,即,即使自第一次尝试以来数据库已被杀死,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()仍然成功。
sudo service mysql stop
如果我要执行任何实际的查询(通过db.Query,db.QueryRow或db.Exec),那么SQL包将与断裂的管道(预计)恐慌。
db.Query
db.QueryRow
db.Exec
难道我做错了什么?
还:go版本go1.7.1 linux / amd64
提前致谢!
第一次连接后, Ping 实际上不会 对数据库执行ping操作 。这很奇怪,而且是错误的,但这就是它的工作方式(直到Go 1.8)。如果连接池中有一个尚未超时的现有连接,Ping会简单地从连接池中删除该连接并将其返回给您,而无需费心检查数据库是否仍然存在。
如果数据库驱动程序支持,Kardianos(撰写了上面的链接文档以及Govendor)在1.8中对此进行了修复。但是,在此之前,Ping无法确定数据库是否仍然存在。