dormbaf90464 2016-08-24 08:04
浏览 46
已采纳

MySql在golang中类型接口的通道不接收值

I am new to golang. I am trying to do concurrent queries to mysql db with golang. I know channels can be of the type interface. When I print tableData (type map) in RunQuery function I am getting the result. I am sending tableData to ch i.e. channel of type interface. In function getdataList I am not getting any value in ch. I don't understand what I am doing wrong.

Following is my code:

package main

import (
    "database/sql"
    "fmt"
    "net/http"
    _ "github.com/go-sql-driver/mysql"
    "log"
)


var db *sql.DB

func getdataList(id int) {
        ch := make(chan interface{})
        done := make (chan bool)
        RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
        go func() {
            for {
            x, ok := <-ch //I am not getting any data in channel here
            if ok {
                fmt.Println(x)
            }else {
                fmt.Println("done")
                done <- true
                return
            }

        }
        }()
    }

func RunQuery (ch chan interface{}, query string, param interface{}) {

    stmt, err := db.Prepare(query)
    if err != nil {
                panic(err.Error())
            }
    defer stmt.Close()
    rows, err := stmt.Query(param)
    columns, err := rows.Columns()
    if err != nil {
        fmt.Println("Failed to get columns", err)
        return
    }
    count := len(columns)
    tableData := make([]map[string]interface{}, 0)
    values := make([]interface{}, count)
    valuePtrs := make([]interface{}, count)
    for rows.Next() {
      for i := 0; i < count; i++ {
          valuePtrs[i] = &values[i]
      }
      rows.Scan(valuePtrs...)
      entry := make(map[string]interface{})
      for i, col := range columns {
          var v interface{}
          val := values[i]
          b, ok := val.([]byte)
          if ok {
              v = string(b)
          } else {
              v = val
          }
          entry[col] = v
      }
      tableData = append(tableData, entry)
  }
    fmt.Pritln(tableData) //here I am getting data in map
    ch <- tableData
}


func dbtest(w http.ResponseWriter, req *http.Request) {

    go getdataList(2)
    go getdataList(3)
}

func main() {
    var err error
    db, err = sql.Open("mysql", "root:@/dbName")
    if err != nil {
        panic(err.Error())  
    }
    defer db.Close()

    http.HandleFunc("/dbTest", dbtest)

    log.Fatal(http.ListenAndServe(":8080", nil))

}
  • 写回答

1条回答 默认 最新

  • doubihuai8468 2016-08-24 08:22
    关注

    The problem with your code is that it is blocking the execution flow before data can be read from the channel. When you call RunQuery from getdataList, RunQuery tries to send data over channel ch. However, nothing is reading from ch because the code to read from it is in getdataList and it's below the call to RunQuery.

    Therefore, RunQuery never returns and the goroutine to read from ch never fires. To fix, You can try running RunQuery as a goroutine as well:

    func getdataList(id int) {
            ch := make(chan interface{})
            done := make (chan bool)
            // run in a goroutine
            go RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
            go func() {
                for {
                x, ok := <-ch //I am not getting any data in channel here
                if ok {
                    fmt.Println(x)
                }else {
                    fmt.Println("done")
                    done <- true
                    return
                }
    
            }
        }()
    }
    

    There is another issue in your code. You are never closing ch. This may result in deadlock. The most ideal place to do this appears to be in RunQuery:

    func RunQuery (ch chan interface{}, query string, param interface{}) {
        // ...
        ch <- tableData
        close(ch)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA