Исключение блокировки базы данных SQLite
Я получаю исключение базы данных из SQLite только для некоторых запросов.
Ниже мой код:
Когда я выполняю любой оператор select, он отлично работает.
Когда я выполняю любой оператор записи на Jobs
Table, он также отлично работает.
Это отлично работает:
ExecuteNonQuery("DELETE FROM Jobs WHERE id=1");
Но так же, как если бы я выполнял запросы для таблицы Employees
, это бросает исключение, которое заблокировано ..
Это исключает Exception:
ExecuteNonQuery("DELETE FROM Employees WHERE id=1");
Ниже приведены мои функции:
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();
}
}
Это исключение:
На строке 103: Cmd.ExecuteNonQuery();
Исключение найдено: Тип: System.Data.SQLite.SQLiteException Сообщение: база данных заблокирована база данных заблокирована Источник: System.Data.SQLite
Stacktrace: на System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt) в System.Data.SQLite.SQLiteDataReader.NextResult() в System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior ведет себя) в System.Data.SQLite.SQLiteCommand.ExecuteReader(поведение CommandBehavior) в System.Data.SQLite.SQLiteCommand.ExecuteNonQuery() в TimeSheet6.DbOp.ExecuteNonQuery(String sql) в d:\Projects\С# Applications\Completed Projects\TimeSheet6\TimeSheet6\DbOp.cs: строка 103
Ответы
Ответ 1
Где-то по пути соединение становится открытым. Избавьтесь от OpenConnection
и CloseConnection
и измените ExecuteNonQuery
на это:
using (SQLiteConnection c = new SQLiteConnection(ConnectionString))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
cmd.ExecuteNonQuery();
}
}
Кроме того, измените способ, которым вы читаете данные:
using (SQLiteConnection c = new SQLiteConnection(ConnectionString))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
...
}
}
}
Не пытайтесь, управлять пулом соединений самостоятельно, как вы здесь. Во-первых, это намного сложнее, чем то, что вы закодировали, но во-вторых, оно обрабатывается уже внутри объекта SQLiteConnection
. Наконец, если вы не используете using
, вы не удаляете эти объекты должным образом, и у вас появятся проблемы, подобные тем, что вы видите сейчас.
Ответ 2
Вы можете использовать оператор 'using', как показано ниже, чтобы убедиться, что соединение и команда расположены правильно даже в исключении
private static void ExecuteNonQuery(string queryString)
{
using (var connection = new SQLiteConnection(
ConnectionString))
{
using (var command = new SQLiteCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
}
Ответ 3
Вы должны закрыть свой DataReader, прежде чем пытаться записать какие-либо данные в базу данных. Использование:
dr.Close();
после завершения использования DataReader.
Ответ 4
Я также получил ту же ошибку здесь:
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();
}
но когда я просто изменил расположение объявления 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();
}
}
Теперь все хорошо. Я надеюсь, что это может сработать и для вас. Если кто-то может сказать, как это произошло, я хотел бы узнать подробности, чтобы улучшить свои знания, пожалуйста.
Ответ 5
В моем случае это было очень глупо с моей стороны, я вносил изменения в браузер SQLite и не нажимал на изменения записи, что блокировало базу данных, которая будет изменена сервисами. После того, как я нажал кнопку "Записать изменения", все запросы на публикацию работали как положено