【发布时间】:2020-05-16 15:37:43
【问题描述】:
我打算同时从多个 goroutine 填充多个 firebird 数据库,为了做到这一点,我的 worker 函数有一个映射 (dbConnections) 保存到数据库的连接(将数据库的名称映射到连接):
func worker() {
dbConnections := map[string]*sql.DB {}
for dbName, dbFileName := range dbFiles {
connection, err := sql.Open("firebirdsql", ("sysdba:master@localhost:3050/" + url.PathEscape(dbsPath + dbFileName)))
err = connection.Ping()
if err != nil {
fmt.Println("Ping failed: ", err.Error()
return
} else {
dbConnections[dbName] = connection
fmt.Println(fmt.Sprintf("Connected to the: %v", dbName))
defer dbConnections[dbName].Close()
}
}
// using the connections to populate databases...
// ...
}
问题是,当我将 worker 函数作为 1 个 goroutine 运行时,一切正常,但是一旦我增加 goroutine 的数量,似乎来自其他 goroutine 的 dbConnections 会变得混乱并且 sql 执行抱怨插入不存在的表!
如何创建dbConnections 以使每个 goroutine 都有自己独特的版本?
编辑:
-
Go版本:v1.14.2.windows-amd64 -
firebirdsql版本:v0.0.0 (f095ac7) (Published: May 5, 2020)
【问题讨论】:
-
这不是地图问题。您的工作者 goroutine 很可能有比赛。这些连接是线程安全的吗?如果不是,可能是多个 goroutine 使用了同一个数据库。
-
为什么不让每个 goroutine 创建自己的连接?
-
“这些连接是线程安全的吗?” @BurakSerdar
*sql.DB对并发是安全的,不是吗? -
_"为什么不让每个 goroutine 创建自己的连接?"_> 我就是这样做的。每个 goroutine 创建自己的一组连接(在函数开头定义,如上面的代码所示)。问题是他们不知何故被来自其他 goroutine 的其他连接弄乱了。
-
@wiki 您可能应该在您的问题中添加
firebirdsql标签,因为它可能是相关的,并且在问题本身中您应该提及您用于与firebirdsql通信的驱动程序。提供的代码中没有任何内容突出“并发使用不正确”,问题将在于您从问题中省略的代码或驱动程序或后端的实现方式。我现在要撤退了,因为我不熟悉firebirdsql,所以我无法评论它或它的任何 Go 驱动程序。
标签: go firebird firebird-3.0