douqiu9529 2018-02-19 19:21
浏览 287
已采纳

执行后事务保持在pg_stat_activity状态

I'm quite new to both PostgreSQL and 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?
  • 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:

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("


 Closed rows without error", "


")
        }
        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, ",") + "
"
        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.

Calling txn.Exec("CLOSE <cursor_name>") didn't help. After that, I had a CLOSE GRABDATA query in idle in transaction state...

Only when I started calling Commit() did the connection actually close. 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?

  • 写回答

1条回答 默认 最新

  • doufu6130 2018-02-19 20:54
    关注

    you want to end transaction, not close a declared cursor. commit does it. 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. After you disconnect the session ends and there's no row in pg_stat_activity at all...

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集