Go读取大量数据,开启多协程,将读取的文件内容导入数据库,出现丢失数据现象

Clouder · 2019-09-09 20:53:00 · 1635 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2019-09-09 20:53:00 的主题,其中的信息可能已经有所发展或是发生改变。

各位大佬,Go新人,昨天写了一个数据库导入工具,从本地文件读取,处理完数据格式后,导入DbFileReadWriteChanel的数据是正确无缺少的,就在开启100协程写入数据,执行完毕后,发现导入后的数据表中缺少了100多条。
\ 清空数据表后,又运行,一次还是缺少,然后进行少量的数据测试,发现,还是丢失,但如果只是使用主线程,导入,则无问题。
初步思考,代码出现问题的范围为一下代码块,请各位大佬协助,帮忙找一下问题所在,谢谢帮助。

//将存入chanel中的数据导入到数据库表中
func (this *DbFileRead) ImportTable(DbFileReadWriteChanel chan DbFileRead, exitChan chan bool) error {

    for {
        v, ok := <-DbFileReadWriteChanel

        if !ok {
            break
        }

        //fmt.Println(v)
        _, sqlErr := Sqldb.Exec("INSERT INTO IPINFO_TABLE VALUES(?,?,?,?,?)", v.Id, v.StartIp, v.EndIp, v.County, v.Local)
        //Sqldb.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})

        if sqlErr != nil {
            log.Printf("sql insert err is %v \n", sqlErr)
            return sqlErr
        }

        fmt.Printf("%d 当前已经完成 \n",v.Id)

    }

    defer Sqldb.Close()

    exitChan <- true

    close(exitChan)

    return nil
}

func main() {
    var dbfr *DbFileRead

    DbFileReadWriteChanel = make(chan DbFileRead, 600000)

    exitChan = make(chan bool,100)

    res, err := dbfr.ReadFile(FILEPATH)

    if err != nil && err == io.EOF {
        log.Printf("get file res success.")
    }

    handleResSlice := dbfr.HandleStringRes(res)

    dbfr.DbWriteChan(handleResSlice) //将handleResSlice 推入chanel中

    //dbfr.ImportTable(DbFileReadWriteChanel, exitChan)
    for i:=0;i<100 ;i++  {
        go dbfr.ImportTable(DbFileReadWriteChanel, exitChan)
    }


    //time.Sleep(time.Second*10)

    for {
        v, ok := <-exitChan
        fmt.Println("exit ", v)
        if !ok {
            break
        }
    }

}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1635 次点击  
加入收藏 微博
1 回复  |  直到 2019-09-10 20:04:37
fenglangjuxu
fenglangjuxu · #1 · 6年之前

我觉得你这有问题 难道你的代码 没有报错么? 至于你丢数据 我没看那方面

 exitChan <- true
close(exitChan)

你上面那个for循环,只有当chan关闭才会退出,但是你的关闭在下面,所以你的加

if len(DbFileReadWriteChanel)==0{
break
}

才会往下走

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传