Maison >développement back-end >Golang >Pourquoi mon code Golang SQLite3 obtient-il une erreur « La base de données est verrouillée » et comment puis-je la corriger ?

Pourquoi mon code Golang SQLite3 obtient-il une erreur « La base de données est verrouillée » et comment puis-je la corriger ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-11 15:19:19776parcourir

Why Does My Golang Sqlite3 Code Get a

Comment corriger l'erreur SQLite3 : la base de données est verrouillée dans Golang

Dans Golang, lorsque vous travaillez avec des bases de données SQLite3, vous pouvez rencontrer l'erreur , "la base de données est verrouillée." Cette erreur indique que plusieurs threads ne peuvent pas utiliser le même fichier de base de données simultanément.

Racine du problème

Même si vous n'avez qu'une seule connexion dans votre programme et que vous fermez tous les résultats de la requête, vous pouvez toujours vous retrouver avec plusieurs descripteurs du fichier de base de données. Ce problème peut être vérifié à l'aide du programme Opendfileview.

Code créant plusieurs descripteurs de fichiers de base de données

Le code suivant montre comment deux descripteurs de fichiers de base de données sont créés :

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
}

Solution

Pour résoudre le problème, vous pouvez différer le Appel rows.Close() comme indiqué ci-dessous :

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

En différant l'appel rows.Close(), vous vous assurez que les lignes sont fermées même si une panique ou une erreur se produit pendant l'itération. Cela permet d'éviter la création de descripteurs de fichiers de base de données supplémentaires et de résoudre l'erreur « la base de données est verrouillée ».

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn