【问题标题】:Implementing unique connections for each goroutine using firebirdsql使用 firebirdsql 为每个 goroutine 实现唯一的连接
【发布时间】: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 都有自己独特的版本?

编辑:

【问题讨论】:

  • 这不是地图问题。您的工作者 goroutine 很可能有比赛。这些连接是线程安全的吗?如果不是,可能是多个 goroutine 使用了同一个数据库。
  • 为什么不让每个 goroutine 创建自己的连接?
  • “这些连接是线程安全的吗?” @BurakSerdar *sql.DB 对并发是安全的,不是吗?
  • _"为什么不让每个 goroutine 创建自己的连接?"_> 我就是这样做的。每个 goroutine 创建自己的一组连接(在函数开头定义,如上面的代码所示)。问题是他们不知何故被来自其他 goroutine 的其他连接弄乱了。
  • @wiki 您可能应该在您的问题中添加firebirdsql 标签,因为它可能是相关的,并且在问题本身中您应该提及您用于与firebirdsql 通信的驱动程序。提供的代码中没有任何内容突出“并发使用不正确”,问题将在于您从问题中省略的代码或驱动程序或后端的实现方式。我现在要撤退了,因为我不熟悉 firebirdsql,所以我无法评论它或它的任何 Go 驱动程序。

标签: go firebird firebird-3.0


【解决方案1】:

正如评论部分中的许多人所提到的,问题是因为线程安全 在firebirdsql 中,尤其是在创建新表时。定义一个mutex 并在mutex.Lock()mutex.Unlock() 之间封装sql 执行方法(这样任何时候只有一个goroutine 可以创建表)解决了这个问题。

【讨论】:

    猜你喜欢
    • 2017-06-18
    • 2019-02-02
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多