web-dev-qa-db-fra.com

Exception SQLite Database Locked

Je reçois la base de données est verrouillée exception de SQLite pour certaines requêtes uniquement.

Voici mon code: Lorsque j'exécute une instruction select, cela fonctionne bien.
Lorsque j'exécute une instruction d'écriture sur la table Jobs, cela fonctionne également très bien.

Cela fonctionne bien:

ExecuteNonQuery("DELETE FROM Jobs WHERE id=1");

Mais de la même manière, si j'exécute des requêtes pour la table Employees, il lance une exception qui la base de données est verrouillée.
Cela lève l'exception:

ExecuteNonQuery("DELETE FROM Employees WHERE id=1");

Voici mes fonctions:

public bool OpenConnection()
{
    if (Con == null)
    {
        Con = new SQLiteConnection(ConnectionString);
    }
    if (Con.State == ConnectionState.Closed)
    {
        Con.Open();
        //Cmd = new SQLiteCommand("PRAGMA FOREIGN_KEYS=ON", Con);
        //Cmd.ExecuteNonQuery();
        //Cmd.Dispose();
        //Cmd=null;
        return true;
    }
    if (IsConnectionBusy())
    {
        Msg.Log(new Exception("Connection busy"));
    }
    return false;
}

public Boolean CloseConnection()
{
    if (Con != null && Con.State == ConnectionState.Open)
    {
        if (Cmd != null) Cmd.Dispose();
        Cmd = null;
        Con.Close();
        return true;
    }

    return false;
}

public Boolean ExecuteNonQuery(string sql)
{
    if (sql == null) return false;
    try
    {
        if (!OpenConnection())
            return false;
        else
        {
            //Tx = Con.BeginTransaction(IsolationLevel.ReadCommitted);
            Cmd = new SQLiteCommand(sql, Con);
            Cmd.ExecuteNonQuery();
            //Tx.Commit();
            return true;
        }
    }
    catch (Exception exception)
    {
        //Tx.Rollback();
        Msg.Log(exception);
        return false;
    }
    finally
    {
        CloseConnection();
    }
}

Voici l'exception: à la ligne 103: Cmd.ExecuteNonQuery();

Exception trouvée: Type: System.Data.SQLite.SQLiteException Message: la base de données est verrouillée la base de données est verrouillée Source: System.Data.SQLite

Stacktrace: sur System.Data.SQLite.SQLite3.Step (SQLiteStatement stmt) sur System.Data.SQLite.SQLiteDataReader.NextResult () sur System.Data.SQLite.SQLiteDataReader..ctor (SQLiteCommand cmd, CommandBehavior se comportent) sur System.Data .SQLite.SQLiteCommand.ExecuteReader (comportement CommandBehavior) sur System.Data.SQLite.SQLiteCommand.ExecuteNonQuery () sur TimeSheet6.DbOp.ExecuteNonQuery (String sql) dans d:\Projects\C # Applications\Completed Projects\TimeSheet6\TimeSheet6\DbOp. cs: ligne 103

42
user1032317

Quelque part en cours de route, une connexion reste ouverte. Débarrassez-vous de OpenConnection et CloseConnection et remplacez ExecuteNonQuery par ceci:

using (SQLiteConnection c = new SQLiteConnection(ConnectionString))
{
    c.Open();
    using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
    {
        cmd.ExecuteNonQuery();
    }
}

De plus, changez la façon dont vous lisez données en ceci:

using (SQLiteConnection c = new SQLiteConnection(ConnectionString))
{
    c.Open();
    using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
    {
        using (SQLiteDataReader rdr = cmd.ExecuteReader())
        {
            ...
        }
    }
}

N'essayez pas, de gérer vous-même le pool de connexions comme si vous étiez ici. Premièrement, c'est beaucoup plus complexe que ce que vous avez codé, mais deuxièmement, il est déjà géré à l'intérieur de l'objet SQLiteConnection. Enfin, si vous ne tirez pas parti de using, vous ne supprimez pas ces objets correctement et vous vous retrouvez avec des problèmes comme ce que vous voyez maintenant.

85
Mike Perrenoud

Vous pouvez utiliser l'instruction 'using' comme ci-dessous, qui garantira que la connexion et la commande sont correctement éliminées, même en cas d'exception

private static void ExecuteNonQuery(string queryString)
{
    using (var connection = new SQLiteConnection(
               ConnectionString))
    {
        using (var command = new SQLiteCommand(queryString, connection))
        {
            command.Connection.Open();
            command.ExecuteNonQuery();
        }
    }
}
14
Damith

Vous devez fermer votre DataReader avant d'essayer d'écrire des données dans la base de données. Utilisation:

dr.Close();

une fois que vous avez fini d'utiliser le DataReader.

2
salman

Dans mon cas, c'était très stupide de ma part, j'effectuais des modifications dans le navigateur SQLite et je ne cliquais pas sur les modifications d'écriture, ce qui bloquait la base de données à modifier par les services. Après avoir cliqué sur le bouton Écrire les modifications, toute la demande de publication a fonctionné comme prévu.

0
Rohan Shenoy

J'obtenais également la même erreur ici:

if (new basics.HindiMessageBox(HMsg, HTitle).ShowDialog()==true)
{
    SQLiteConnection m_dbConnection = new SQLiteConnection(MainWindow.con);
    m_dbConnection.Open();
    sql = "DELETE FROM `users`  WHERE `id`=" + SelectedUser.Id;
    command = new SQLiteCommand(sql, m_dbConnection);
    command.ExecuteNonQuery();
    m_dbConnection.Close();
    LoadUserDG();
}

mais quand je viens de changer l'emplacement de la déclaration SQLiteConnection

public partial class User : Window
{
    SQLiteCommand command;
    string sql;
    AddUser AddUserObj;
    List<basics.users> usersList;
    basics.users SelectedUser;
    SQLiteConnection m_dbConnection;

    // ...

    private void DeleteBtn_Click(object sender, RoutedEventArgs e)
    {
        // ...
        if (new basics.HindiMessageBox(HMsg, HTitle).ShowDialog()==true)
        {
            m_dbConnection = new SQLiteConnection(MainWindow.con);
            m_dbConnection.Open();
            sql = "DELETE FROM `users`  WHERE `id`=" + SelectedUser.Id;
            command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();
            m_dbConnection.Close();
            LoadUserDG();
        }
}

Tout va bien maintenant. J'espère que cela fonctionnera aussi pour vous. Si quelqu'un peut dire comment cela s'est produit, j'aimerais connaître les détails pour améliorer mes connaissances, s'il vous plaît.

0
RAM DANE