首頁 >後端開發 >Golang >為什麼我的 Golang Sqlite3 程式碼出現「資料庫已鎖定」錯誤,如何修復它?

為什麼我的 Golang Sqlite3 程式碼出現「資料庫已鎖定」錯誤,如何修復它?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-11 15:19:19776瀏覽

Why Does My Golang Sqlite3 Code Get a

如何修正Golang 中的Sqlite3 錯誤:資料庫被鎖定

在Golang 中,使用Sqlite3 資料庫時,您可能會遇到以下錯誤,「資料庫已鎖定。」此錯誤表示多個執行緒不能同時使用同一個資料庫檔案。

問題根源

即使您的程式中可能只有一個連接並關閉對於所有查詢結果,您可能仍然會得到資料庫檔案的多個句柄。可以使用 Opendfileview 程式驗證此問題。

建立多個資料庫檔案句柄的程式碼

以下程式碼示範如何建立兩個資料庫檔案句柄:

import "log"

import (
    "database/sql"
    "fmt"
)

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
    }
    defer rows.Close() // Missing defer
    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
}

解決問題,您可以延後rows.Close()調用,如下所示:

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

透過推遲 rows.Close() 調用,您可以確保即使在執行過程中發生恐慌或錯誤,行也會關閉迭代。這有助於防止建立額外的資料庫檔案句柄並解決「資料庫已鎖定」錯誤。

以上是為什麼我的 Golang Sqlite3 程式碼出現「資料庫已鎖定」錯誤,如何修復它?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn