我已经在Golang实现了一个复杂的csv导入脚本。我使用了Workerpool实现。在这个Workerpool中,工作人员会运行上千个小csv文件,对产品进行分类、标记和品牌化。他们都写入同一个数据库表。到目前为止一切顺利。
我所面临的问题是,如果我选择了2个以上的工人,进程崩溃,并随机显示以下消息
工作流程为
foreach (csv) {
workerPool.submit(csv)
}
func worker(csv) {
foreach (line) {
import(line)
}
}
import(line) {
product = get(line)
product.category = determine_category(product)
product.brand = determine_brand(product)
save(brand)
product.tags = determine_tags(product)
//and after all
save(product)
}
我尝试将保存()调用 Package 在事务中,但没有用。
现在我有以下问题:
- MySQL适合并发保存到1个表吗?
1.如果需要事务来完成此操作,则应将其设置在何处? - Go SQL驱动程序(错误总是发生在packets.go:1102中)适合这样做吗?
1.有人能帮我吗(也许雇几个小时)?
我完全卡住了。如果有帮助的话,我也可以分享源代码。但是我首先想知道你猜这是我的代码还是一个普遍的问题。
1条答案
按热度按时间nwnhqdif1#
在每个goroutine(或者线程,对于使用线程的语言)中打开一个新的数据库连接。
MySQL的协议是有状态的,这意味着如果多个goroutine试图使用同一个连接,请求和响应会变得非常混乱。
在goroutine之间共享任何其他类型的有状态协议连接时,你也会遇到同样的问题。
例如,ftp也是一个有状态的协议,这可能更容易理解,一个客户端goroutine可能会发送一个类似“get file x”的消息,而响应应该是一系列包含该文件内容的消息,如果另一个goroutine试图使用同一个连接,而这个请求/响应正在进行中,第二个goroutine会读取它没有请求的文件的数据包,而第一个请求该文件的goroutine会发现它所期望的数据包已经被读取了。
类似地,MySQL的协议不支持多个客户端goroutine共享一个连接。