是否需要调用db.Close()? [英] Does db.Close() need to be called?

查看:148
本文介绍了是否需要调用db.Close()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,Go最困难的部分是了解如何组织代码.表面上看起来似乎非常简单,但是每次我尝试做任何事情时,我都会遇到循环导入或诸如导出的func Start返回未导出的类型models.dbStore,这可能很烦人"之类的事情.

So far the hardest part of Go has been understanding how to organize code. It seems incredibly simple on it's face but every time I've tried to do anything I run into circular imports or things like "exported func Start returns unexported type models.dbStore, which can be annoying to use".

使用以下代码如何调用 db.Close(),或者我真的不明白我应该如何为模型提供数据库.这就是我所拥有的:

Using the following code how do I call db.Close() or am I really not understanding how I'm supposed to provide the database to my models. Here's what I've got:

App.go

package app

import (
    "database/sql"

    // Comment
    _ "github.com/mattn/go-sqlite3"
)

var (
    // DB The database connection
    db *sql.DB
)

// Setup Sets up the many many app settings
func Setup() {
    d, err := sql.Open("sqlite3", "./foo.db")
    if err != nil {
        panic(err)
    }

    // TODO: How does the DB get closed?
    // defer db.Close()
    db = d
}

// GetDB Returns a reference to the database
func GetDB() *sql.DB {
    return db
}

Users.go

package models

import (
    "github.com/proj/org/app"
)

// User struct
type User struct {
    ID int
}

// CreateUser Creates a user
func (u *User) CreateUser() (int64, error) {

    // For the sake of brevity just make sure you can
    // "connect" to the database
    if err := app.GetDB().Ping(); err != nil {
        panic(err)
    }

    return 1234, nil
}

main.go

package main

import (
    "fmt"
    "net/http"

    _ "github.com/mattn/go-sqlite3"
    "github.com/proj/org/app"
    "github.com/proj/org/models"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "You are home")
}

func subscribeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Subscribing...")
    u := models.User{}

    u.CreateUser()

}

func main() {
    fmt.Println("Running")

    app.Setup()

    http.HandleFunc("/", homeHandler)
    http.HandleFunc("/subscribe", subscribeHandler)

    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        panic(err)
    }
}

我考虑过要做一个 app.Shutdown(),但这不适用于我最普通的用例CTRL-C.看来,如果我不关闭数据库,数据库连接只会增加……只是试图了解.

I thought about doing a app.Shutdown() but that wouldn't work for my most normal use case which is CTRL-C. It would seem if I don't close the database the DB connections would just grow... Just trying to understand.

推荐答案

不必关闭数据库.

返回的数据库可以安全地被多个goroutine并发使用维护自己的空闲连接池.因此,打开功能应该只调用一次.几乎不需要关闭数据库.

The returned DB is safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB.

来自: https://golang.org/pkg/database/sql/#Open

当程序退出时,所有打开的连接都会关闭,它不会在以太坊中保持打开状态,等待您的程序再次启动,因此不必担心在CTRL-C应用程序时连接会增长".

When your program exits then any open connection is closed, it does not stay open somewhere in the ether awaiting your program to start again, so do not worry about the connections "growing" when you CTRL-C your app.

但是,如果您仍要关闭它,则可以像使用 GetDB 一样导出 CloseDB 函数.

If, however, you still want to close it, then you can just export a CloseDB function the same way you do with GetDB.

App.go

// ...

func CloseDB() error {
    return db.Close()
}

main.go

// ...

func main() {
    // ...

    app.Setup()
    defer app.CloseDB()

    // ...

}

这篇关于是否需要调用db.Close()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆