1

アプリで問題が発生しています。これはデスクトップ アプリケーションであり、キャッシュ用に作成され、c#マルチSqlite DBスレッドです。

私の問題はcaching operation、他のスレッドからの操作と競合することがあります。

誰でも私を助けることができますか、このジレンマを解決する方法はありますか?

データベースのロックを解除することを考えています (おそらくプログラムを再起動します) が、これは良い方法ではないことはわかっています。

4

2 に答える 2

5

同様の質問についてSOを検索すると、コンセンサスは自分でロックを行う必要があるようです。SqliteConnection一部の回答は、書き込みを行うすべてのスレッドに同じオブジェクトを渡すことを示していました。私はそれが問題を解決するとは思わないが。

同時書き込み/読み取りを再考することをお勧めします。スレッドが何らかの作業を行ってから、そのスレッド内のデータベースに保存すると想定しています。スレッドが何らかの作業を行い、出力を返すように書き直します。データを db に保存するプロセスは、作業を実行するプロセスと組み合わせる必要はありません。ロックはshared読み取り用であるため、同時読み取りは変更なしで機能するはずです。確かに、書き込みと読み取りが同時に発生するシナリオが存在する可能性があります。その場合、エラーが再びポップアップします。

lock objectグローバルを使用して、それを使用してすべての書き込み/読み取りを同期/シリアル化する方が簡単かもしれないと思います。ただし、それを行った瞬間に、db アクセスをシングル スレッド化したことになります。これは、最終目標が何であるかによって答えが決まる質問の 1 つです。

ところで、アプリケーション レベルではなく、データベース レベルのトランザクションを使用すべきではありませんか? http://msdn.microsoft.com/en-us/library/86773566.aspxのようなもの

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    SqlCommand command = connection.CreateCommand();
    SqlTransaction transaction;

    // Start a local transaction.
    transaction = connection.BeginTransaction("SampleTransaction");

    // Must assign both transaction object and connection 
    // to Command object for a pending local transaction
    command.Connection = connection;
    command.Transaction = transaction;

    try
    {
        command.CommandText =
            "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
        command.ExecuteNonQuery();
        command.CommandText =
            "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
        command.ExecuteNonQuery();

        // Attempt to commit the transaction.
        transaction.Commit();
        Console.WriteLine("Both records are written to database.");
    }
    catch (Exception ex)
    {
        Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
        Console.WriteLine("  Message: {0}", ex.Message);

        // Attempt to roll back the transaction. 
        try
        {
            transaction.Rollback();
        }
        catch (Exception ex2)
        {
            // This catch block will handle any errors that may have occurred 
            // on the server that would cause the rollback to fail, such as 
            // a closed connection.
            Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
            Console.WriteLine("  Message: {0}", ex2.Message);
        }
    }
}
于 2013-10-03T09:15:47.537 に答える
1

SQLiteDatabaseC# Applicationにリンクして、同じことをしたかったのです。私は得た:

Database is locked(5)

同様に、コードでトランザクションを使用してこれを修正しました。使用したトランザクションの例を次に示します。

 using (TransactionScope tran = new TransactionScope())
 {
     //Perform action on SQLite Database here.


     tran.Complete();
 }
于 2013-10-03T07:30:29.127 に答える