2013-07-11 2 views
31

Я получаю База данных заблокирована Исключение из SQLite для некоторых запросов.SQLite Database Locked exception

Ниже мой код: Когда я выполняю любой оператор выбора, он отлично работает.
Когда я выполняю любой оператор записи на Jobs Таблица также отлично работает.

Это прекрасно работает:

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

Но точно так же, если я выполнения запросов для Employees таблицы он бросает исключение, которое база данных заблокирована.
Это бросает исключение:

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

Exception Найдено: Тип: 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 \ C# Applications \ Completed Projects \ TimeSheet6 \ TimeSheet6 \ DbOp.cs: строка 103

+0

Убедитесь, что вы закрыли соединение, выполнив ваш запрос. –

+0

Да, я закрыл все соединения и удалил объекты команд. – coding

+0

Я сделал много отладки за этим. Это не похоже на проблему открытого соединения. – coding

ответ

74

Где-то по пути соединение становится оставлен открытым. Избавьтесь от 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, вы не располагаете этими объектами должным образом, и вы получите проблемы, подобные тем, что вы видите сейчас.

+0

Спасибо .. Я попробую это так. – coding

+0

Могут ли возникнуть какие-либо другие причины такого исключения, кроме как неправильно размещать объекты. – coding

+0

@ кодирование, да. Всегда есть другие способы блокировки файлов, но неправильная обработка объектов подключения (например, исходный код) является основным подозреваемым. –

13

Вы можете использовать «используя» заявление, как показано ниже, что будет убедиться, что команда соединение & УТИЛИЗИРОВАТЬСЯ правильно, даже в исключении

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

Спасибо .. Я буду использовать этот подход. – coding

+0

Спасибо за ваш совет. Я реализовал его, и теперь такие исключения не выбрасываются. – coding

0
I was also getting the same error here 

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 declearation место

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

теперь все в порядке. надеюсь, что это может сработать и для вас. Если кто-то может сказать, как это произойдет, скажите, что я хотел бы знать, чтобы улучшить свои знания.

+0

Вы должны использовать «Использование», где это возможно! Как показал Майк Перренуд и Дамит. «Использование» было изобретено для целей управления/безопасности, вы действительно должны его использовать. – tmighty

0

Перед тем, как писать данные в базу данных, вы должны закрыть свой DataReader. Использование:

dr.Close(); 

после того, как вы закончите использовать DataReader.