0
点赞
收藏
分享

微信扫一扫

探索设计模式的魅力:抽象工厂模式的艺术

Ichjns 1天前 阅读 0

        database/sql包提供了一个围绕SQL(或类SQL)数据库的通用接口。在使用这个包时,经常会看到一些使用方法上的错误。下面让我们来深入了解下常见的错误。

1.忘记sql.Open 不一定与数据库建立连接

当使用sql.Open时,一个常见的错误是期望这个函数能够建立与数据库的连接:

db, err := sql.Open("mysql", dsn)
if err != nil {
    return err
}

但情况并不一定如此。根据文档中所说:

        Open可能只是验证它的参数,而不创建与数据库的连接。

        实际上,这种行为取决于所使用的SQL驱动。对于一些驱动,sql.Open并不建立连接;它只是为以后的使用做准备。因此,与数据库的第一个连接可能会延迟建立。

        为什么需要了解这种行为呢?例如,在某些情况下,我们希望只在我们知道的所有的依赖关系都已正确设置并可到达之后,服务才是准备好的。如果不知道这一点,服务有可能在错误的配置下接收流量。

如果我们想确保使用 sql.Open 的函数保证底层数据库是可以到达的,那应该使用Ping方法:

db, err := sql.Open("mysql", dsn)
if err != nil {
    return err
}
if err := db.Ping(); err != nil {
    return err
}

 Ping迫使代码建立一个连接来确保数据源是有效的、数据库是可达的。请注意,Ping的一个替代方案是PingContext,它要求提供一个额外的上下文,传递什么时候应该取消Ping或超时。

        尽管可能是反直觉的,但我们应记住sql.Open不一定能建立一个连接,第一个连接可能是延迟建立的。如果想测试我们的配置并确定数据库是可以到达的,那应该在sql.Open之后调用 Ping或pingContext 方法。

2. 忘记连接池导致的问题

        正如默认的HTTP客户端和服务端提供的默认行为在生产环境中并不一定生效,了解在Go中如何处理数据库是很有必要的。sql.Open 返回一个*sql.DB结构体。这个结构体并不代表一个单一的数据库连接,它代表一个连接池。这一点值得注意,这样我们就不会打算手动实现它了。池中的连接可以有两种状态:

    举报

    相关推荐

    0 条评论