执行后,事务保持在pg_stat_activity状态

时间:2018-02-19 19:21:14

标签: postgresql go gorp

我对PostgreSQL和golang都很陌生。主要是,我想了解以下内容:

  • 为什么我需要使用Commit语句来关闭连接,而另外两个Close调用没有做到这一点?
  • 也会赞赏关于我正在使用游标的正确/错误方式的指示。

在下面的函数中,我使用gorp创建CURSOR,逐行查询Postgres DB并将每一行写入writer函数:

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_activityidle in transaction州保持开放状态, FETCH ALL in GRABDATA查询。

致电txn.Exec("CLOSE <cursor_name>")没有帮助。之后,我在CLOSE GRABDATA州内进行了idle in transaction查询...

只有当我开始调用Commit()时,连接才真正关闭。我想也许我需要调用Commit在转换上执行任何操作,但如果是这样的话 - 为什么我在没有调用它的情况下得到了查询结果?

1 个答案:

答案 0 :(得分:1)

您希望结束事务,而不是关闭声明的游标。 commit做到了。 you can run multiple queries in one transaction - 这就是为什么你看到结果而不提交。

当您运行语句(例​​如,pg_stat_activity.stateactive)时,begin transaction;值为:fetch cursosidle in transaction当您当前未运行时语句,但在您运行idleend后,交易仍然开始且最后commit,因此交易已结束。断开会话结束后,pg_stat_activity中根本没有行...

相关问题