问题内容 我在golang上写api,遇到了错误。在一个请求服务器返回错误后,sql 数据库已关闭。我想通过上下文传输数据库连接。 main.Go func main() {
我在golang上写api,遇到了错误。在一个请求服务器返回错误后,sql 数据库已关闭。我想通过上下文传输数据库连接。
func main() {
app := fiber.new()
db, err := sqlx.connect("pgx", os.getenv("postgresql_url"))
if err != nil {
panic(err)
}
if err = db.ping(); err != nil {
panic(err)
}
db.setmaxopenconns(10)
db.setmaxidleconns(5)
db.setconnmaxlifetime(5 * time.minute)
db.setconnmaxidletime(5 * time.minute)
defer db.close()
configure_router.configurerouter(app, db)
if err = app.listen(os.getenv("port")); err != nil {
log.fatalln(err)
}
}
configure_router.go
func configurerouter(app *fiber.app, db *sqlx.db) {
//middlewares
app.use(logger.new(logger.config{
fORMat: "[${ip}]:${port} ${time} ${status} - ${method} ${path}\n",
}))
app.use(cors.new(cors.config{
//alloworigins: "Http://localhost:3000",
allowheaders: "origin, content-type, accept",
}))
app.use("/api", func(ctx *fiber.ctx) error {
ctx.context().setuservalue("dbconn", db)
return ctx.next()
})
//authentication endpoints
app.post("api/reGISter", register.register)
app.post("api/auth/login", login.login)
}
注册.go
func register(ctx *fiber.ctx) error {
conn := ctx.context().uservalue("dbconn").(*sqlx.db)
var in in
if err := ctx.bodyparser(&in); err != nil {
return make_response.makeinforesponse(ctx, fiber.statusunprocessableentity, 1, err.error())
}
if in.email == "" || in.passWord == "" {
return make_response.makeinforesponse(ctx, fiber.statusbadrequest, 1, "incorrect data input")
}
elementexist := false
err := conn.get(&elementexist, "select exists(select email from users where email = $1)", in.email)
// here programm fall in second request
if err != nil {
return make_response.makeinforesponse(ctx,fiber.statusinternalservererror, 1, err.error())
}
if elementexist {
return make_response.makeinforesponse(ctx, fiber.statusbadrequest, 1, "user already registered!")
}
passwordhash, err := hash_passwords.hashpassword(in.password)
if err != nil {
return err
}
_, err = conn.exec("insert into users (email, password_hash) values ($1, $2)", in.email, passwordhash)
if err != nil {
return make_response.makeinforesponse(ctx, fiber.statusinternalservererror, 1, err.error())
}
return make_response.makeinforesponse(ctx, fiber.statusok, 0, "registration was successful!")
}
如果我在 /api/register 中发送请求并且用户已经在第一个请求中注册,我会得到
要求:
{
"email": "[email protected]",
"password": "123123123"
}
第一反应:
{
"error_code": 0,
"message": "user already registered!"
}
但是如果我想发送另一个请求,我会得到:
{
"error_code": 1,
"message": "sql: database is closed",
}
我想通过上下文传输数据库连接。
不要。这不仅是不好的做法,而且实际上是 fasthttp.requestctx
本身在每次请求后关闭数据库。上下文应仅包含请求特定值。全局数据库连接几乎不是特定于请求的。
请参阅 setuservalue
的文档,特别是最后一个段落:
从顶层requesthandler返回后,所有值都会从ctx中删除。此外,在从 ctx 中删除值之前,会在每个实现 io.closer 的值上调用 close 方法。
一个快速修复方法是在闭包中捕获数据库:
func Register(db *sqlx.DB) (fn func(*fiber.Ctx) error) {
return func(ctx *fiber.Ctx) error {
// ...
elementExist := false
err := db.Get(&elementExist, "select exists(select email from users where email = $1)", in.Email)
// ...
}
}
// ...
// delete this or comment it out
// app.Use("/api", func(ctx *fiber.Ctx) error {
// ctx.Context().SetUserValue("dbConn", db)
// return ctx.Next()
// })
app.Post("api/register", register.Register(db))
以上就是数据库连接在第一个请求后关闭的详细内容,更多请关注编程网其它相关文章!
--结束END--
本文标题: 数据库连接在第一个请求后关闭
本文链接: https://lsjlt.com/news/561458.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0