Pgxpool 在扫描时返回"pool closed"错误



我正在尝试在一个新的go应用程序中实现pgxpool。我一直得到一个";池关闭";尝试扫描结构后出错。

连接后,进入的pgx记录器会给我这个。我以为pgxpool应该保持开放。

{"级别":"信息","消息":"关闭连接","pid":5499,"时间":"2022-02-24T16:36:33+10:30"}

这是我的路由器代码

func router() http.Handler {
var err error
config, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatalln(err)
}
log.Println(os.Getenv("DATABASE_URL"))
logrusLogger := &logrus.Logger{
Out:          os.Stderr,
Formatter:    new(logrus.JSONFormatter),
Hooks:        make(logrus.LevelHooks),
Level:        logrus.InfoLevel,
ExitFunc:     os.Exit,
ReportCaller: false,
}
config.ConnConfig.Logger = NewLogger(logrusLogger)
db, err := pgxpool.ConnectConfig(context.Background(), config)
if err != nil {
log.Fatalln(err)
}
defer db.Close()
--- minio connection
rs := newAppResource(db, mc)

然后,在一个帮助文件中,我设置了资源

type appResource struct {
db *pgxpool.Pool
mc *minio.Client
}
// newAppResource function to pass global var
func newAppResource(db *pgxpool.Pool, mc *minio.Client) *appResource {
return &appResource{
db: db,
mc: mc,
}
}

有";池关闭";错误发生在该代码的末尾

func (rs *appResource) login(w http.ResponseWriter, r *http.Request) {
var user User
var login Login
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields() // catch unwanted fields
err := d.Decode(&login)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err != nil {
fmt.Println("can't decode JSON", err)
}
if login.Email == "" {
log.Println("empty email")
return
}
log.Println(login.Email)
log.Println(login.Password)
if login.Password == "" {
log.Println("empty password")
return
}
// optional extra check
if d.More() {
http.Error(w, "extraneous data after JSON object", http.StatusBadRequest)
return
}
sqlStatement := "SELECT user_id, password FROM users WHERE active = 'true' AND email = ?"
row := rs.db.QueryRow(context.Background(), sqlStatement, login.Email)
err = row.Scan(&user.UserId, &user.Password)
if err == sql.ErrNoRows {
log.Println("user not found")
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

您似乎正在执行以下操作:

func router() http.Handler {
db, err := pgxpool.ConnectConfig(context.Background(), config)
if err != nil {
log.Fatalln(err)
}
defer db.Close()
return appResource{db: db}
}

这样做的问题是,defer db.Close()在函数router()结束时运行,而这是在实际使用返回的pgxPool.Pool之前(稍后处理http请求时将使用返回的http.Handler(。尝试使用关闭的pgxPool.Pool会导致您看到的错误。

最简单的解决方案是简单地删除defer db.Close(),但是您也可以考虑将调用db.Close()作为干净关闭过程的一部分(只要您在处理请求,它就需要保持打开状态(。

您使用的pgxpool与标准库不同;然而,我相信标准库文档中给出的建议适用于此:

很少需要关闭数据库。

相关内容

最新更新