sql - 在 golang 中使用准备好的语句时,是否总是需要延迟 stmt.close()?

标签 sql database go

根据此处的帖子,http://go-database-sql.org/modifying.html ,没有延迟 stmt.close()。但是,在 sql 包中有一个 stmt.close() API。我似乎无法找到有关在使用准备语句时是否有必要推迟关闭 stmt 的信息。因此,问题 - 当我在 golang 中使用准备好的语句时,我是否总是需要推迟 stmt.close() ?

最佳答案

使用 defer不是要求,它是便利并且提供安全。重要的是,如果您创建/准备一个语句(它在内部使用一些资源,也可能在数据库服务器本身中使用资源),那么在将来的某个时候,您会调用它的 Close() 方法以释放由它分配的资源。

即使您的函数突然结束,延迟函数也会执行(例如,您有一个早期的 return 语句,或者即使您的函数出现 panic),因此使用 defer 关闭资源会给出您可以确保您的代码不会泄漏资源和/或内存。

请注意,defer 只会在周围的函数返回时运行。在某些情况下,提前关闭语句是可能的,甚至是合适的,而不是等到周围的函数返回。一个很好的例子是,如果您有一个执行多次迭代的 for 循环,您不希望每次迭代中创建的所有语句都保留资源,直到 for 循环完成.在这种情况下,建议在下一次迭代开始之前关闭资源。在这种情况下,您只需编写 stmt.Close() 而不是 defer stmt.Close(),因为后者不会立即关闭语句,只有当函数返回。

另请注意,将循环主体“外包”到一个单独的函数也将使您有可能在该单独的函数中使用 defer,延迟关闭将在下一次迭代开始之前发生。一个变体可能是您在循环体中使用匿名函数(函数文字),您也有机会在其中使用 defer,例如:

for _, v := range values {
    func() {
        stmt, err := db.Prepare("INSERT INTO users(name) VALUES(?)")
        if err != nil {
            // handle error
            return
        }
        defer stmt.Close()

        // Use stmt...
    }()
}

关于sql - 在 golang 中使用准备好的语句时,是否总是需要延迟 stmt.close()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49233207/

相关文章:

for-loop - 是否不鼓励在 Go 中使用单行 for 循环或 if 语句?

typescript - 错误处理文件 :multipart: NextPart: EOF

php - 如何防止 PHP 中的 SQL 注入(inject)?

sql - 计算每天两个日期时间字段之间的平均时差

MySQL(多个)带子查询的左连接 - 未知列

mysql - 更改 NetBeans 中现有的 MySQL 表

java - 无法看到通过 Spring Boot Java 创建的表

mysql - 对字段进行分组并创建新列的 SQL 命令

mysql - 使用复合键在 GORM 中对现有数据库关系建模

go - 如何安装插件