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
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.
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();
}
}
}
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.
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.
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.