1

アプリケーションに 5 つのテーブルを持つデータベースを作成しました。私のデータベースは別のスレッドから更新されています。ログを見ると、データベースが既に開いている場合、データベースを開くときにデータベースがロックされた例外があることがわかります。

私の友人の 1 人は、この問題を回避するために常にコンテンツ プロバイダーを使用するように勧めてくれました。彼によると、コンテンツ プロバイダーは同時実行の問題を独自に管理しているのですか?

他のアプリケーションとデータを共有したくない場合は、コンテンツ プロバイダーを使用することをお勧めしますか?

4

2 に答える 2

4

ほとんどの場合、読み書きロックを使用するだけで十分だと思います。

次のように書いたとします。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MyDatabase extends SQLiteOpenHelper
{
    private static final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);

    private static void beginReadLock()
    {
        rwLock.readLock().lock();
    }

    private static void endReadLock()
    {
        rwLock.readLock().unlock();
    }

    private static void beginWriteLock()
    {
        rwLock.writeLock().lock();
    }

    private static void endWriteLock()
    {
        rwLock.writeLock().unlock();
    }

次に、次のようにタスクを実行できます。

    public static void doSomething()
    {
        SQLiteDatabase sldb = null;

        try
        {
            beginReadLock();

            MyDatabase mydb = new MyDatabase();
            sldb = mldb.getReadableDatabase();
            ......
        }
        catch (Exception e)
        {
            ......
        }
        finally
        {
            if (sldb != null)
            {
                try
                {
                    sldb.close();
                }
                catch (Exception e) {}
            }

            endReadLock();
        }
    }

beginReadLock()endReadLock( )で読み取り操作を囲みます。同様に、書き込み操作をbeginWriteLock()endWriteLock( ) で囲みます。

数か月前、上記のソリューションにより、複数のスレッドがデータベースを同時に読み取り/書き込みオープンしようとしていた私自身のデータベース ロックの問題を解決できました。

于 2012-06-26T18:54:11.303 に答える
1

問題は、データベースへの複数のデータベース接続を使用していることです。したがって、いくつかのスレッドがテーブルを同時に更新しようとし、これらすべてのスレッドがデータベースに対して異なる接続を持っています。

すべてのスレッドでこの問題を回避するには、データベースへの同じ接続を使用する必要があります。つまり、すべてのスレッドがデータベースへの同じ接続を使用する必要があります (これは SQLiteDabase オブジェクトによって表されます)。

さらに、sqlite ファイルにファイル ブロックがあるため、複数のスレッドを使用してデータベース アップグレードのパフォーマンスを向上させることはできません (データベースを操作するために 1 つのスレッドのみを使用することをお勧めします)。複数のスレッドを使用する場合は、データベースへの同じ接続を使用する必要があります。この場合、Android がロックを管理します。

ここで見つけることができるこの問題の議論: http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-lockingとここ: Android での SQLite のベスト プラクティスは何ですか?

于 2012-06-26T18:30:59.100 に答える