I'm intending to populate multiple firebird databases from multiple goroutines concurrently and in order to do that my worker
function has a map (dbConnections
) that holds the connections to databases (maps the name of the database to the connection):
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...
// ...
}
The problem is that when I run worker
function as just 1 goroutine, everything works just fine, but as soon as I increase the number of goroutines, it seems that dbConnections
from other goroutines gets messed up and sql executions complain about insertion into non existing tables!
How can I create dbConnections
in such a way that every goroutine, has its own unique version of it?
Edit:
Go
version: v1.14.2.windows-amd64firebirdsql
version: v0.0.0 (f095ac7) (Published: May 5, 2020)As many mentioned in the comment section, the problem was because of thread-safety
in firebirdsql
and especially when creating new tables. Defining a mutex
and enclosing the sql execution method between mutex.Lock()
and mutex.Unlock()
(so that only one goroutine can create tables at any given time) solved the problem.