database - golang sqlite 数据库连接池

标签 database sqlite error-handling go

当我在读取数据库的同时调用数据库写入时,我遇到了 SQLite 在我的机器上扔 Spanner 的问题。当不同的方法碰巧同时尝试访问数据库时,就会发生这种情况。

我所做的与 this thread 中所做的相似,接受的答案解释了如何使用数据库事务来避免数据库锁定。

这是我的一些代码:

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 locked
Database storage complete!
2014/09/09 18:33:11 database is locked
exit status 1

我不希望我的程序在数据库锁定时停止,我希望它将数据存储在内存中并继续其业务,直到数据库解锁并且我可以重试。

是否有一些标准的方法可以实现这一点,可能是某种队列或数据结构,或者是否有特定于数据库的方法来解决这个问题?

为什么输出数据库存储完成!后程序退出?

编辑:

我相信我已经解决了这个问题,但我不能确定。我正在使用 goroutines 和包范围的数据库连接。以前,我的代码中的每个函数在调用时都会初始化一个数据库连接。现在,我在包顶部定义了一个用于 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 请求,以便可以从正在运行的程序中读取数据并通过网络将数据传输到数据请求者,无论是本地请求还是外部请求。我还没有遇到问题。

最佳答案

documentation说:

A single connection instance and all of its derived objects (prepared statements, backup operations, etc.) may NOT be used concurrently from multiple goroutines without external synchronization.

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

当您使用 goroutines 时,您必须使用单独的数据库连接。

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

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

关于database - golang sqlite 数据库连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25751830/

相关文章:

ios - 想给Sqlite数据库添加上标数据

c# - 验证我的MVC错误处理

python-3.x - 如何获取过去的Python错误?

database - 我该如何处理从liquibase updateDatabase ant任务中得到的错误

java - 如何将本地数据库的数据同步到远程数据库

Python 和 sqlite3 - 导入和导出数据库

java - ANDROID:如何让应用程序将所有错误日志记录在数据库中?

python - 我如何关联 2 个 Django 选择字段

SQL 查询组织结构图?

sql - 我需要格式化返回的列值,但该列可能不存在,在这种情况下,我需要获取其余的列数据