英文:
Why does defer stmnt.Close() seem to block my http.Redirect?
问题
为什么我的 defer stmnt.Close()
看起来会阻塞我的 http.Redirect
,导致网站无限加载而无法重定向?
但是如果我移除 defer stmnt.Close()
,重定向就能正常工作?
err = db.QueryRow("SELECT steamid FROM accounts WHERE steamid = ?", ids).Scan(&steamid)
if err != nil {
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to connect to database. Try again in a bit.", 500)
}
switch {
case len(profile.Response.Players) == 0:
common.WriteLog("Failed to look you up in the steam database. Try again in a bit.", r)
http.Error(w, "Failed to look you up in the steam database. Try again in a bit.", 500)
case err == sql.ErrNoRows:
stmnt, err := db.Query("INSERT INTO accounts SET steamid=?", ids)
if err != nil {
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to insert your account to the database. Try again in a bit.", 500)
}
defer stmnt.Close() // <<<< The suspect
// Insert Account
http.Redirect(w, r, "/", 303)
case err != nil:
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to insert your account to the database. Try again in a bit.", 500)
default:
// Login User
http.Redirect(w, r, "/", 303)
}
你的代码中使用了 defer stmnt.Close()
来延迟关闭数据库连接。defer
关键字会在函数返回之前执行 Close()
方法。然而,如果在执行 defer stmnt.Close()
之前发生了重定向,那么 Close()
方法将会被阻塞,导致重定向无法正常进行。
通过移除 defer stmnt.Close()
,你可以解决这个问题,因为数据库连接会在函数结束时自动关闭。这样,重定向就能够正常工作了。
英文:
Why does my defer stmnt.Close()
seem to block my http.Redirect
from redirecting it just hangs on the website infinitely trying to load.
But if I remove the defer stmnt.Close()
it redirects just fine?
err = db.QueryRow("SELECT steamid FROM accounts WHERE steamid = ?", ids).Scan(&steamid)
if err != nil {
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to connect to database. Try again in a bit.", 500)
}
switch {
case len(profile.Response.Players) == 0:
common.WriteLog("Failed to look you up in the steam database. Try again in a bit.", r)
http.Error(w, "Failed to look you up in the steam database. Try again in a bit.", 500)
case err == sql.ErrNoRows:
stmnt, err := db.Query("INSERT INTO accounts SET steamid=?", ids)
if err != nil {
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to insert your account to the database. Try again in a bit.", 500)
}
defer stmnt.Close() // <<<<< The suspect
// Insert Account
http.Redirect(w, r, "/", 303)
case err != nil:
common.WriteLog(err.Error(), r)
http.Error(w, "Failed to insert your account to the database. Try again in a bit.", 500)
default:
// Login User
http.Redirect(w, r, "/", 303)
}
答案1
得分: 3
使用db.Exec
而不是db.Query
。
> Exec执行一个查询,不返回任何行。
与
> Query执行一个返回行的查询。
至于为什么,我猜测mysql的Rows.Close
正在等待数据在连接上:
func (rows *mysqlRows) Close() error {
mc := rows.mc
if mc == nil {
return nil
}
if mc.netConn == nil {
return ErrInvalidConn
}
// 从流中删除未读的数据包
err := mc.readUntilEOF()
rows.mc = nil
return err
}
这是永远不会发生的。
参见这个示例。
英文:
Use db.Exec
instead of db.Query
.
> Exec executes a query without returning any rows.
vs
> Query executes a query that returns rows
As for why, I would guess the mysql Rows.Close
is waiting for data on the connection:
func (rows *mysqlRows) Close() error {
mc := rows.mc
if mc == nil {
return nil
}
if mc.netConn == nil {
return ErrInvalidConn
}
// Remove unread packets from stream
err := mc.readUntilEOF()
rows.mc = nil
return err
}
Which is never going to happen.
See this for example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论