【问题标题】:Sqlite3 error: database is locked in golangSqlite3 错误:数据库被锁定在 golang
【发布时间】:2015-12-05 09:27:50
【问题描述】:

我在 golang 中使用 sqlite3 数据库,但出现错误:“数据库已锁定。”

我知道不能有多个线程使用同一个数据库文件。

虽然我的程序中只有一个连接,但我关闭了所有查询结果,但它总是会创建 2 或 3 个数据库文件句柄。

我可以使用 Opendfileview 程序检查这一点。

以下代码创建两个数据库文件句柄。

func main() {
    database, tx, err := getDatabaseHandle()
    if err != nil {
        log.Fatal(err)
    }
    defer database.Close()
    dosomething(database, tx)
}
func dosomething(database *sql.DB, tx *sql.Tx) error {
    rows, err := database.Query("select * from sometable where name=?","some")
    if err != nil {
        return err
    }
    if rows.Next() {
        ...
    }
    rows.Close()
    //some insert queries
    tx.Commit()
}
func getDatabaseHandle() (*sql.DB, *sql.Tx, error) {
    database, err := sql.Open("sqlite3", dbPath)
    if err != nil {
        fmt.Println("Failed to create the handle")
        return nil, nil, err
    }
    if err2 := database.Ping(); err2 != nil {
        fmt.Println("Failed to keep connection alive")
        return nil, nil, err
    }
    tx, err := database.Begin()
    if err != nil {
        return nil, nil, err
    }
    return database, tx, nil
}

【问题讨论】:

  • 您必须提供更多信息,尤其是说明您的问题的代码。
  • 程序运行前没有数据库文件句柄,但程序运行后有 2 个句柄。所以我认为只是我的程序本身锁定了数据库文件。
  • 您在getDatabaseHandle 开始交易,但我在任何地方都看不到tx.Committx.Rollback。这可能是问题吗?

标签: go sqlite


【解决方案1】:

尝试推迟rows.Close()

if err != nil {
    return err
}
defer rows.Close()
if rows.Next() {
    ...
}

【讨论】:

  • 你说到点子上了。我通过关闭代码中的所有“行”解决了我的问题。虽然你的答案不是我问题的确切解决方案,但我会检查你的答案。谢谢你的回答。
  • 太棒了!太感谢了!我什至不知道您应该关闭数据库处理程序之外的行;我认为这将是“自动的”,但显然不是。此外,语句也会出现同样的问题;我正在使用godoc.org/github.com/mattn/go-sqlite3,并且在使用后还有一个关闭语句的函数。一旦我这样做了,可怕的“数据库已锁定”错误就消失了,这让我头疼了好几天!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多