为了账号安全,请及时绑定邮箱和手机立即绑定

golang sqlite 数据库连接池

golang sqlite 数据库连接池

Go
达令说 2021-08-16 16:20:35
当我在读取数据库的同时调用数据库写入时,SQLite 在我的机器中抛出一个扳手时遇到了麻烦。当不同的方法碰巧同时尝试访问数据库时,就会发生这种情况。我正在做的类似于这个线程中正在做的事情,接受的答案解释了如何使用数据库事务来避免数据库锁定。这是我的一些代码:stmt, err := dbtx.Prepare(`statement`)if err != nil {    log.Fatal(err)}_, err = stmt.Exec(values, values, values)if err != nil {            log.Fatal(err)}err = dbtx.Commit()if err != nil {    fmt.Println("database lock?")    fmt.Println(err)    dbtx.Rollback()}fmt.Println("Database storage complete!")令人困惑的是程序在输出后存在:database lock?database is lockedDatabase storage complete!2014/09/09 18:33:11 database is lockedexit status 1我不希望我的程序因数据库锁定而停止,我希望它将数据存储在内存中并继续其业务,直到数据库解锁,我可以再试一次。是否有一些标准的方法可以实现这一点,也许是某种队列或数据结构,或者是否有特定于数据库的方法来解决这个问题?为什么程序输出后退出Database storage complete!?编辑:我相信我已经解决了这个问题,但我不能确定。我正在使用 goroutines 和包范围的数据库连接。以前,我的代码中的每个 func 在被调用时都会初始化一个数据库连接。现在,我在包的顶部定义了一个用于 DB 连接的“全局”变量,并在任何例程开始之前进行了初始化。简而言之,代码如下:var nDB *sql.DB稍后在主函数中...mypkg.InitDB()go mypkg.RunDatabaseOperations()mypkg.BeginHTTPWatcher(rtr)InitDB() 定义如下:func InitDB() {    fmt.Println("Init DB ...")    var err error    nDB, err = sql.Open("sqlite3", "./first.db")    if err != nil {        log.Fatal(err)    }    if nDB == nil {        log.Fatal(err)    }    fmt.Printf("nDB: %v\n", ODB)    fmt.Println("testing db connection...")    err2 := nDB.Ping()    if err2 != nil {        log.Fatalf("Error on opening database connection: %s", err2.Error())    }}因此,RunDatabaseOperations定期扫描在线资源中的数据,并在发生更改时将其存储到数据库中(每隔几秒一次)。BeginHTTPWatcher侦听 HTTP 请求,因此可以从正在运行的程序中读取数据,并通过网络将数据传输到数据的请求者,无论是本地请求还是外部请求。我还没有遇到问题。
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

该文件说:

单个连接实例及其所有派生对象(准备好的语句、备份操作等)不能在没有外部同步的情况下从多个 goroutine 同时使用。

(这是一个不同的 SQLite 驱动程序,但此限制也适用于您的。)

使用 goroutine 时,必须使用单独的数据库连接。

默认情况下,SQLite 在遇到被另一个事务锁定的数据库时会立即中止。为了允许更多的并发,您可以通过设置繁忙超时来告诉它等待另一个事务完成。

使用BusyTimeout函数,如果你的 SQLite 驱动有它,或者直接执行PRAGMA busy_timeout SQL 命令。


查看完整回答
反对 回复 2021-08-16
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

请发布更多您的代码,以便我们可以更全面地了解发生了什么。

但是,这里有一些想法。Golang 默认池数据库连接(虽然,CENTOS 似乎可能不是......)。此外,您的程序正在“暂停”,因为它正在等待来自数据库连接池的打开连接。如果您希望程序的其余部分在此期间继续运行,您应该将其作为异步函数运行 -在此处查看goroutines。这将有效地导致您的程序按照您的需要排队,因为连接将按照它们可用时请求的顺序进行分配。如果您对内部结构感兴趣,请在此处阅读更多内容。

如果您需要一些关于 goroutine 外观的代码片段,请告诉我们。


查看完整回答
反对 回复 2021-08-16
  • 2 回答
  • 0 关注
  • 419 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信