我打算同时从多个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...
// ...
}
问题是,当我仅以1个goroutine运行worker
函数时,一切正常,但是一旦我增加了goroutine的数量,似乎其他goroutine的dbConnections
就会混乱并且sql执行程序会报错关于插入到不存在的表中!
我如何以每个goroutine都有其独特版本的方式创建dbConnections
?
编辑:
Go
版本:v1.14.2.windows-amd64firebirdsql
版本:v0.0.0 (f095ac7) (Published: May 5, 2020)正如评论部分中提到的,问题出在线程安全性上在firebirdsql
中,尤其是在创建新表时。定义mutex
并将sql执行方法放在mutex.Lock()
和mutex.Unlock()
之间(以便在任何给定时间只有一个goroutine可以创建表)解决了该问题。