Go uses Mysql packet to report error: database is closed?

topic description

The go-sql-driver/mysql driver used by

initializes the connection pool object in another package, and sets * sq;.DB as a global variable to reference in another package, uses Query to get the MySQL connection, and the query keeps reporting errors?

related codes

package database

import (
    "database/sql"

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

var Db *sql.DB

func init() {
    var err error
    Db, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/blog?charset=utf8")
    if err != nil {

        fmt.Println("conn failed!")
        log.Fatal(err.Error())
    }
    defer Db.Close()

    fmt.Println(&Db)

    Db.SetMaxOpenConns(2000)
    Db.SetMaxIdleConns(1000)

    err = Db.Ping()
    if err != nil {
        log.Fatal(err.Error())
    }

    fmt.Println("db inti")
}
package controllers

import (
    . "build-web-application/004-blog/database"
    //"database/sql"
    "fmt"
    "github.com/gin-gonic/gin"
    _ "github.com/go-sql-driver/mysql"
    "log"
)

func GetPosts(c *gin.Context) {

    rows, err := Db.Query(`SELECT * FROM t_post`)
    if err != nil {
        log.Fatal(err)
    }
    //    defer rows.Close()

    for rows.Next() {
        var id int
        var post string
        err = rows.Scan(&id, &post)
        fmt.Println(id)
        fmt.Println(post)

    }

}

Dec.08,2021

look at the place where the red line is drawn, you are already close, so you can still use it outside.
it is recommended to understand the meaning of defer first.
be sure to look at the basics first, step by step, and don't be impatient


@ diligent little dust is right. The result of using defer Db.Close () in init () is that when the init function returns, it closes the database connection, and then calls it in GetPosts (), it will report an error that the database has been closed.

the right thing to do is to turn it off after you have fully used Db. I wrote an article about defer before. You can read it: https://codeshelper.com/a/11.

.

defer Db.Close ()
is executed at the end of the init function.
so this type of resource does not need to be closed by defer

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1e52965-451d7.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1e52965-451d7.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?