web-dev-qa-db-ja.com

SQLiteデータベースロック例外

データベースがロックされていますSQLiteからの例外が一部のクエリでのみ取得されています。

以下にコードを示します。selectステートメントを実行すると、正常に動作します。
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();

例外が見つかりました:タイプ:System.Data.SQLite.SQLiteExceptionメッセージ:データベースがロックされていますデータベースがロックされていますソース:System.Data.SQLite

Stacktrace:System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)at System.Data.SQLite.SQLiteDataReader.NextResult()at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd、CommandBehavior behave)at System.Data d:\ Projects\C#Applications\Completed Projects\TimeSheet6\TimeSheet6\DbOpのTimeSheet6.DbOp.ExecuteNonQuery(String sql)のSystem.Data.SQLite.SQLiteCommand.ExecuteNonQuery()の.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) cs:line 103

42
user1032317

接続が開いたままになる途中のどこかに。 OpenConnectionCloseConnectionを取り除き、ExecuteNonQueryを次のように変更します。

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

さらに、read dataの方法を次のように変更します。

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

試行しないでくださいあなたがここにいるように自分で接続プーリングを管理します。 1つ目は、コーディングしたものよりもはるかに複雑ですが、2つ目はSQLiteConnectionオブジェクト内で既に処理されています。最後に、usingを利用していない場合は、これらのオブジェクトを適切に破棄しないにしているため、現在表示されているような問題が発生します。

85
Mike Perrenoud

次のように「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();
        }
    }
}
14
Damith

データベースにデータを書き込む前に、DataReaderを閉じる必要があります。つかいます:

dr.Close();

dataReaderの使用が終了した後。

2
salman

私の場合、それは非常に愚かだったので、SQLiteブラウザーで変更を行っていましたが、書き込みの変更をクリックしませんでした。 [変更を書き込む]ボタンをクリックした後、すべての投稿リクエストが期待どおりに機能しました。

0
Rohan Shenoy

ここでも同じエラーが発生しました:

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

今はすべて順調です。これがあなたにも役立つことを願っています。誰かがこれが起こった方法を言うことができるなら、私は私の知識を改善するために詳細を知りたいです。

0
RAM DANE