Golang-Postgres ..关闭数据库连接不适用于特定查询
Golang-Postgres ..Closing database connection not working for particular query
我正在使用 golang 访问 postgresql。
这是我的功能
for {
db, err := database.GetNewConnection(dbname)
err = db.QueryRow("SELECT COALESCE(COUNT(1),0) FROM table").Scan(&count)
if count == 0 {
var insert = "INSERT INTO table(last_update_time,next_update_time,schedule_frequency)" +
"VALUES(,,)"
prep_ins, err := db.Prepare(insert)
if err != nil {
return
}
_, err = prep_ins.Exec(cur_time, 1464718530, 86400)
if err != nil {
return
}
defer prep_ins.Close()
defer db.Close()
} else {
var sel_str = "SELECT next_update_time FROM table"
prep_update, err := db.Prepare(sel_str)
if err != nil {
return
}
_, err = prep_update.Exec()
if err != nil {
defer prep_update.Close()
return
}
defer prep_update.Close()
defer db.Close()
}
time.Sleep(10 * 60 * time.Second)
}
每 10 分钟,此函数将 运行 并执行这些语句。它工作正常,但连接将处于空闲状态。我正在使用 pg_stat_activity
检查,状态仅为空闲。每 10 分钟,将创建一个新连接并进入空闲状态 state.so 并继续增加。我不知道为什么会这样。
提前致谢。
for
循环是无限循环,永远不会return。这意味着 defer 永远不会被执行,连接也不会被关闭。您需要在循环结束时添加显式 db.Close()
。
如果您不需要每次执行任务时都需要新的连接,也可以将 db
的初始化移出循环。您可以只创建一个连接并重用它。如果这样做,请将 defer
语句移动到 db
的初始化下方。如果数据库操作 return 出现一些错误,则 defer 将关闭连接。
db, err := database.GetNewConnection(dbname)
if err != nil {
return fmt.Errorf("Error in creating database connection: %+v", err)
}
defer db.Close()
for {
// ...
db.Close()
}
通过这样做,您可以确保在函数 (https://blog.golang.org/defer-panic-and-recover)
的每个 return 路径 put 上关闭连接
如果您仍将 db
初始化留在循环中,请删除 defers
,因为它们只会添加到延迟堆栈,而数据库连接将被显式关闭。
正如@abhink 所指出的,由于永久 运行 for
循环,您的 defer 语句未被调用。您使用 for
循环计划执行一段代码的实现不是最佳的。
您应该改用 golang 频道。
package main
import (
"fmt"
"time"
)
func main() {
//You can configure your tick for 10 mnts.
tick := time.Tick(100 * time.Millisecond)
//some exit condition
exit := time.After(1000 * time.Millisecond)
for {
select {
case <-tick:
poke()
case <-exit:
fmt.Println("Exit")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
func poke() {
fmt.Println("Opening connection")
defer fmt.Println("Closing connection")
fmt.Println("Inserting into Database")
}
您可以更改 pock()
函数以将记录插入数据库。您可以将自动收报机配置为每 10 mnts 自动计时。由于每个 tick 都会触发一个新的函数调用,因此一旦 pock()
函数执行完成,您的 defer 就会被调用。
参考这个 go playground 片段 https://play.golang.org/p/1fQgbmI9LY
defer
函数只在函数returns时被调用。在你的循环中,当循环处于活动状态时,defer db.Close()
永远不会执行,因此函数永远不会被调用。
您可以将 for
中的逻辑包装在 闭包 中以实现延迟:
for{
func(){
// inner code
}()
time.Sleep(10 * 60 * time.Second)
}
我正在使用 golang 访问 postgresql。 这是我的功能
for {
db, err := database.GetNewConnection(dbname)
err = db.QueryRow("SELECT COALESCE(COUNT(1),0) FROM table").Scan(&count)
if count == 0 {
var insert = "INSERT INTO table(last_update_time,next_update_time,schedule_frequency)" +
"VALUES(,,)"
prep_ins, err := db.Prepare(insert)
if err != nil {
return
}
_, err = prep_ins.Exec(cur_time, 1464718530, 86400)
if err != nil {
return
}
defer prep_ins.Close()
defer db.Close()
} else {
var sel_str = "SELECT next_update_time FROM table"
prep_update, err := db.Prepare(sel_str)
if err != nil {
return
}
_, err = prep_update.Exec()
if err != nil {
defer prep_update.Close()
return
}
defer prep_update.Close()
defer db.Close()
}
time.Sleep(10 * 60 * time.Second)
}
每 10 分钟,此函数将 运行 并执行这些语句。它工作正常,但连接将处于空闲状态。我正在使用 pg_stat_activity
检查,状态仅为空闲。每 10 分钟,将创建一个新连接并进入空闲状态 state.so 并继续增加。我不知道为什么会这样。
提前致谢。
for
循环是无限循环,永远不会return。这意味着 defer 永远不会被执行,连接也不会被关闭。您需要在循环结束时添加显式 db.Close()
。
如果您不需要每次执行任务时都需要新的连接,也可以将 db
的初始化移出循环。您可以只创建一个连接并重用它。如果这样做,请将 defer
语句移动到 db
的初始化下方。如果数据库操作 return 出现一些错误,则 defer 将关闭连接。
db, err := database.GetNewConnection(dbname)
if err != nil {
return fmt.Errorf("Error in creating database connection: %+v", err)
}
defer db.Close()
for {
// ...
db.Close()
}
通过这样做,您可以确保在函数 (https://blog.golang.org/defer-panic-and-recover)
的每个 return 路径 put 上关闭连接如果您仍将 db
初始化留在循环中,请删除 defers
,因为它们只会添加到延迟堆栈,而数据库连接将被显式关闭。
正如@abhink 所指出的,由于永久 运行 for
循环,您的 defer 语句未被调用。您使用 for
循环计划执行一段代码的实现不是最佳的。
您应该改用 golang 频道。
package main
import (
"fmt"
"time"
)
func main() {
//You can configure your tick for 10 mnts.
tick := time.Tick(100 * time.Millisecond)
//some exit condition
exit := time.After(1000 * time.Millisecond)
for {
select {
case <-tick:
poke()
case <-exit:
fmt.Println("Exit")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
func poke() {
fmt.Println("Opening connection")
defer fmt.Println("Closing connection")
fmt.Println("Inserting into Database")
}
您可以更改 pock()
函数以将记录插入数据库。您可以将自动收报机配置为每 10 mnts 自动计时。由于每个 tick 都会触发一个新的函数调用,因此一旦 pock()
函数执行完成,您的 defer 就会被调用。
参考这个 go playground 片段 https://play.golang.org/p/1fQgbmI9LY
defer
函数只在函数returns时被调用。在你的循环中,当循环处于活动状态时,defer db.Close()
永远不会执行,因此函数永远不会被调用。
您可以将 for
中的逻辑包装在 闭包 中以实现延迟:
for{
func(){
// inner code
}()
time.Sleep(10 * 60 * time.Second)
}