2011-11-12 30 views
22

私はたくさんのトピックを読んだことがありますが、質問の答えを見つけることはできません。同時読み書きが可能ですか?SQLiteの同時読み込みと書き込み

いくつかのデータを更新するバックグラウンドスレッドがあり、UIにはDBに格納された小さなデータが必要です。したがって、UIスレッドではSELECT操作が実行されます。しかし、更新が進行中のときはブロックされます。その結果、UIは数秒間フリーズします。

誰でもDBからの読み込みに成功していますか?


iPhoneでDBに読み書きすることができます。そのような違いの理由は、ネイティブsqlite関数のラッパーの同期実装にあるのでしょうか?

+5

"UIスレッドではSELECT操作が実行されます" - > UIスレッドから取得します。 – hovanessyan

+2

SELECT名FROM some_table WHERE _id = 名前を数秒間表示しないでください。フリーズするほど良くはありません。 – HighFlyer

答えて

54

WALモードをサポート(先行書き込みログを):

、先行書き込みログ(デフォルト)有効になっていない場合は読み取りと発生する書き込みをするために、それは可能 ではありませんデータベース上で同じ 時間。データベースを変更する前に、書き込み側は暗黙的にデータベース上の 排他ロックを取得し、書き込みが完了するまで読者がデータベース にアクセスできないようにします。

逆に、先読みログが有効になっていると、書き込み操作 が別のログファイルに記録され、読み込みを に同時に進めることができます。書き込みが進行中の間に、他のスレッド 上の読者は、書き込み前の状態をデータベース が認識し始めます。書き込みが完了すると、他のスレッドのリーダーは、 はデータベースの新しい状態を認識します。代わりのbeginTransactionの)WALモード使用beginTransactionNonExclusive(トランザクションを開始するには

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()

()。 のbeginTransaction()はEXCLUSIVEモードでトランザクションを開始しますが、beginTransactionNonExclusive()が始まるIMMEDIATEモードで1つの

  • EXCLUSIVEモードはREAD_UNCOMMITTEDの接続を除いて、他のデータベース接続を意味しない排他ロック(http://www.sqlite.org/lockingv3.html#excl_lock)は、データベースを読み取ることができます使用していますトランザクションが完了するまでデータベースを書き込むことはできません。
  • IMMEDIATEモードでは、予約されたロック(http://www.sqlite.org/lockingv3.html#reserved_lock)を使用して、他のデータベース接続がデータベースに書き込むことができない、またはBEGIN IMMEDIATEまたはBEGIN EXCLUSIVEしかし、他のプロセスは引き続きデータベースから読み取ることができます。シンプルな言葉で

:(私たちはREAD_UNCOMMITTED接続使用しませんので、書き込みトランザクションが開始する前の状態を - >http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Dirty_reads)を別のスレッドが書き込んでいる間にIMMEDIATEモード用beginTransactionNonExclusive()を呼び出し、私たちが読むことができます。

+0

驚くばかり!この情報は非常に重要ですが、見落とされました。あなたの詳細な答えをありがとう! – HighFlyer

+0

WALモードでは、API 16未満のすべてのAPIをサポートできなくなります。 –

+6

WALモードはAPI 11 on(Honeycomb)からサポートされています。 API 11とAPI 16の違いは、Context.MODE_ENABLE_WRITE_AHEAD_LOGGINGモードを使用してAPI 16でWALモードでデータベースを実際に開き、API11-15の使用可能なモードの1つで開き、WALモードに切り替える必要があることですSQLiteDatabase.enableWriteAheadLogging()を使用します。 WALモードでの開きはかなり速いですが、それはあなたが持っているものです。ハニカムの前には、WALモードがないという意味ですが、アプリの動作は遅くなりますが、少なくとも他の副作用はないはずです。 –

1

&は同時に書き込むことはできません。ただし、SQLiteデータベースクラスが正しく設定されている場合(DB &ヘルパークラスのインスタンス)、異なるスレッドがDB接続を同期的に取得して、顕著な遅延がないようにする必要があります。

また、UIスレッドを使用してバックエンド作業(DBへの書き込み)をしようとしているようです。あなたはこれをしてはいけません。 AsyncTaskを作成して、UIスレッドで処理する代わりにこれを処理します。

SQLiteOpenHelperのドキュメントを参照してください。ここでこれについても話している以前の投稿があります:What are the best practices for SQLite on Android?

3

同時に読み書きすることはできません。 SQLiteは、サーバレスのファイルベースのデータベースです。 SQLite FAQ:

から

「任意のプロセスを書きたいときは、その更新の期間中、全体のデータベースファイルをロックする必要があります。しかし、通常は数ミリ秒かかること。他のプロセスだけにライターを待ちます他の組み込みSQLデータベースエンジンは、通常、一度に1つのプロセスをデータベースに接続することしかできません。アンドロイド3.0と高いSQLiteDatabasesで

+3

答えが間違っているため、投票が遅れました。ハニカムから(すでに回答が与えられていたときに)それは同時に読む/書くことができます(自分の答えを参照してください) –

+0

"ハニカムの中の"というオリジナルの質問には何も表示されません – dnuttle

+9

質問は、 "同時読み書きが可能ですか?"という答えは、 "同時に読むことも書き込むこともできません"です。あなたがHoneycomb以上にいる場合、あなたができるので、答えは間違っています。 –

3

API 11からAndroidはWALモードをサポートしています。トランザクション中に元のデータを変更しないようにするため、トランザクションの実行時に他のスレッドを読み取ることができます。あなたはWALモードの詳細については私の記事をチェックすることができます。

http://www.skoumal.net/en/parallel-read-and-write-in-sqlite/

ます。また、UIスレッドでデータベースクエリを実行しないようにしてください。それは常に低迷してUIをブロックすることができます。

関連する問題