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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题