简体   繁体   English

执行后事务保持在pg_stat_activity状态

[英]Transaction stays in pg_stat_activity state after execution

I'm quite new to both PostgreSQL and golang. 我对PostgreSQL和golang都是新手。 Mainly, I am trying to understand the following: 我主要是想了解以下内容:

  • Why did I need the Commit statement to close the connection and the other two Close calls didn't do the trick? 为什么我需要Commit语句来关闭连接,而其他两个Close调用却不能解决问题?
  • Would also appreciate pointers regarding the right/wrong way in which I'm going about working with cursors. 还要感谢有关我使用游标的正确/错误方式的指针。

In the following function, I'm using gorp to make a CURSOR, query my Postgres DB row by row and write each row to a writer function: 在以下函数中,我使用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)
    }
}

In the defer section, I would initially, only Close the rows , but then I saw that pg_stat_activity stay open in idle in transaction state, with the FETCH ALL in GRABDATA query. defer部分,我会开始,只有Closerows ,但后来我看到pg_stat_activity保持开放idle in transaction状态下,与FETCH ALL in GRABDATA查询。

Calling txn.Exec("CLOSE <cursor_name>") didn't help. 调用txn.Exec("CLOSE <cursor_name>")没有帮助。 After that, I had a CLOSE GRABDATA query in idle in transaction state... 之后,我idle in transaction状态下处于idle in transaction状态的CLOSE GRABDATA查询...

Only when I started calling Commit() did the connection actually close. 只有当我开始调用Commit()时,连接才真正关闭。 I thought that maybe I need to call Commit to execute anything on the transation, but if that's the case - how come I got the result of my queries without calling it? 我以为也许我需要调用Commit在转换上执行任何操作,但是如果是这样的话-我怎么不查询就得到查询结果?

you want to end transaction, not close a declared cursor. 您想要结束事务,而不是关闭已声明的游标。 commit does it. commit做到这一点。 you can run multiple queries in one transaction - this is why you see the result without committing. 您可以在一个事务中运行多个查询 -这就是为什么您无需提交即可看到结果的原因。

the pg_stat_activity.state values are: active when you run the statement (eg, begin transaction; or fetch cursos ), idle in transaction when you don't currently run statements, but the transaction remains begun and lastly idle , after you run end or commit , so the transaction is over. pg_stat_activity.state值是: active当你运行该语句(如begin transaction;fetch cursos ), idle in transaction时,你不运行当前语句,但成交仍然开始和最后idle ,在运行后endcommit ,因此事务结束。 After you disconnect the session ends and there's no row in pg_stat_activity at all... 断开连接后,会话结束,并且pg_stat_activity中完全没有行...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM