簡體   English   中英

golang sqlite數據庫連接池

[英]golang sqlite database connection pooling

當我在與讀取相同的時間調用數據庫寫入時,我遇到了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 locked
Database storage complete!
2014/09/09 18:33:11 database is locked
exit status 1

我不希望我的程序暫停數據庫鎖,我希望它將數據存儲在內存中並繼續其業務直到數據庫解鎖,我可以再試一次。

是否有一些標准方法可以實現這一點,可能是某種類型的隊列或數據結構,還是有特定於數據庫的方法來解決這個問題?

為什么程序在輸出Database storage complete!后退出Database storage complete!

編輯:

我相信我已經解決了這個問題,但我無法確定。 我正在使用goroutines和一個程序包范圍的數據庫連接。 以前,我的代碼中的每個函數都在調用時初始化數據庫連接。 現在,我有一個“全局”變量用於在包頂部定義的數據庫連接,並在任何例程開始之前進行初始化。 這里的代碼簡而言之:

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請求,以便可以從正在運行的程序中讀取數據,並通過BeginHTTPWatcher數據傳輸到數據的請求者,無論是本地請求還是外部請求。 我還沒有遇到任何問題。

文件說:

單個連接實例及其所有派生對象(預處理語句,備份操作等)可能無法在沒有外部同步的情況下從多個goroutine同時使用。

(這是一個不同的SQLite驅動程序,但此限制也適用於您的。)

使用goroutine時, 必須使用單獨的數據庫連接。

默認情況下,SQLite在遇到另一個事務鎖定的數據庫時立即中止。 為了允許更多的並發性,您可以通過設置忙超時告訴它等待另一個事務完成。

如果您的SQLite驅動程序有,請使用BusyTimeout函數,或直接執行PRAGMA busy_timeout SQL命令。

請發布更多代碼,以便我們更全面地了解正在發生的事情。

但是,這里有幾個想法。 默認情況下Golang池數據庫連接(盡管,CENTOS似乎不是......)。 此外,您的程序正在“暫停”,因為它正在等待來自數據庫連接池的打開連接。 如果您希望程序的其余部分在此期間繼續,則應將其作為異步函數運行 - 請在此處查看goroutines 這將有效地使您的程序按照您的意願排隊,因為連接將按照它們可用時請求的順序進行分配。 如果您對內部感興趣,請閱讀更多內容

如果您需要一些關於goroutine外觀的代碼片段,請告訴我們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM