事务执行后保持pg_stat_activity状态
Transaction stays in pg_stat_activity state after execution
我对 PostgreSQL 和 golang 都很陌生。主要是,我试图了解以下内容:
- 为什么我需要 Commit 语句来关闭连接而其他两个
Close
调用却没有成功?
- 也将感谢有关我将要使用游标的 right/wrong 方式的指点。
在下面的函数中,我使用 gorp
创建一个 CURSOR,逐行查询我的 Postgres 数据库并将每一行写入一个写入函数:
func(txn *gorp.Transaction,
q string,
params []interface{},
myWriter func([]byte, error)) {
cursor := "DECLARE GRABDATA NO SCROLL CURSOR FOR " + q
_, err := txn.Exec(cursor, params...)
if err != nil {
myWriter(nil, err)
return
}
rows, err := txn.Query("FETCH ALL in GRABDATA")
if err != nil {
myWriter(nil, err)
return
}
defer func() {
if _, err := txn.Exec("CLOSE GRABDATA"); err != nil {
fmt.Println("Error while closing cursor:", err)
}
if err = rows.Close(); err != nil {
fmt.Println("Error while closing rows:", err)
} else {
fmt.Println("\n\n\n Closed rows without error", "\n\n\n")
}
if err = txn.Commit(); err != nil {
fmt.Println("Error on commit:", err)
}
}()
pointers := make([]interface{}, len(cols))
container := make([]sql.NullString, len(cols))
values := make([]string, len(cols))
for i := range pointers {
pointers[i] = &container[i]
}
for rows.Next() {
if err = rows.Scan(pointers...); err != nil {
myWriter(nil, err)
return
}
stringLine := strings.Join(values, ",") + "\n"
myWriter([]byte(stringLine), nil)
}
}
在 defer
部分,我最初只会 Close
rows
,但后来我看到 pg_stat_activity
保持打开状态 idle in transaction
, 使用 FETCH ALL in GRABDATA
查询。
致电 txn.Exec("CLOSE <cursor_name>")
没有帮助。之后,我在 idle in transaction
状态下进行了 CLOSE GRABDATA
查询...
只有当我开始调用 Commit()
时,连接才真正关闭。我想也许我需要调用 Commit 来执行事务中的任何操作,但如果是这样的话 - 为什么我没有调用它就得到了我的查询结果?
您想结束事务,而不是关闭已声明的游标。 commit
做到了。
you can run multiple queries in one transaction - 这就是为什么你不提交就看到结果的原因。
pg_stat_activity.state
值是:active
当您 运行 语句(例如,begin transaction;
或 fetch cursos
)时,idle in transaction
您当前没有 运行 语句,但交易仍然开始,最后 idle
,在您 运行 end
或 commit
之后,因此交易结束。断开连接后,会话结束并且 pg_stat_activity
中根本没有行...
我对 PostgreSQL 和 golang 都很陌生。主要是,我试图了解以下内容:
- 为什么我需要 Commit 语句来关闭连接而其他两个
Close
调用却没有成功? - 也将感谢有关我将要使用游标的 right/wrong 方式的指点。
在下面的函数中,我使用 gorp
创建一个 CURSOR,逐行查询我的 Postgres 数据库并将每一行写入一个写入函数:
func(txn *gorp.Transaction,
q string,
params []interface{},
myWriter func([]byte, error)) {
cursor := "DECLARE GRABDATA NO SCROLL CURSOR FOR " + q
_, err := txn.Exec(cursor, params...)
if err != nil {
myWriter(nil, err)
return
}
rows, err := txn.Query("FETCH ALL in GRABDATA")
if err != nil {
myWriter(nil, err)
return
}
defer func() {
if _, err := txn.Exec("CLOSE GRABDATA"); err != nil {
fmt.Println("Error while closing cursor:", err)
}
if err = rows.Close(); err != nil {
fmt.Println("Error while closing rows:", err)
} else {
fmt.Println("\n\n\n Closed rows without error", "\n\n\n")
}
if err = txn.Commit(); err != nil {
fmt.Println("Error on commit:", err)
}
}()
pointers := make([]interface{}, len(cols))
container := make([]sql.NullString, len(cols))
values := make([]string, len(cols))
for i := range pointers {
pointers[i] = &container[i]
}
for rows.Next() {
if err = rows.Scan(pointers...); err != nil {
myWriter(nil, err)
return
}
stringLine := strings.Join(values, ",") + "\n"
myWriter([]byte(stringLine), nil)
}
}
在 defer
部分,我最初只会 Close
rows
,但后来我看到 pg_stat_activity
保持打开状态 idle in transaction
, 使用 FETCH ALL in GRABDATA
查询。
致电 txn.Exec("CLOSE <cursor_name>")
没有帮助。之后,我在 idle in transaction
状态下进行了 CLOSE GRABDATA
查询...
只有当我开始调用 Commit()
时,连接才真正关闭。我想也许我需要调用 Commit 来执行事务中的任何操作,但如果是这样的话 - 为什么我没有调用它就得到了我的查询结果?
您想结束事务,而不是关闭已声明的游标。 commit
做到了。
you can run multiple queries in one transaction - 这就是为什么你不提交就看到结果的原因。
pg_stat_activity.state
值是:active
当您 运行 语句(例如,begin transaction;
或 fetch cursos
)时,idle in transaction
您当前没有 运行 语句,但交易仍然开始,最后 idle
,在您 运行 end
或 commit
之后,因此交易结束。断开连接后,会话结束并且 pg_stat_activity
中根本没有行...