[解決済み] AndroidでSQLiteを使用する際に、並行処理の問題を回避するにはどうすればよいですか?
質問
AndroidアプリでSQLiteデータベースのクエリを実行する際のベストプラクティスは何でしょうか?
AsyncTaskのdoInBackgroundからinserts、deletes、selectクエリを実行しても問題ないですか?それともUI Threadを使用すべきですか?データベースクエリはquot;heavy"であり、アプリをロックする可能性があるのでUIスレッドを使用すべきではないと推測します - 結果として アプリケーションが応答しない (ANR)です。
複数のAsyncTasksがある場合、それらは接続を共有すべきですか、それともそれぞれ接続を開くべきですか?
このようなシナリオでのベストプラクティスはありますか?
解決方法は?
挿入、更新、削除、読み込みは、一般的に複数のスレッドからOKですが、Bradの 答え は正しくありません。 接続の作成方法と使用方法に注意する必要があります。 データベースが破損していなくても、更新の呼び出しに失敗する状況があります。
基本的な答えです。
SqliteOpenHelperオブジェクトは、1つのデータベース接続を保持します。 読み込みと書き込みの接続を提供しているように見えますが、実際にはそうではありません。 読み取り専用を呼び出せば、書き込み用のデータベース接続を取得することができます。
つまり、1つのヘルパーインスタンスに1つのDB接続です。 複数のスレッドから使用する場合でも、一度に1つの接続です。 SqliteDatabaseオブジェクトは、Javaロックを使用して、アクセスをシリアライズしておく。 そのため、100のスレッドが1つのDBインスタンスを持つ場合、実際のディスク上のデータベースへの呼び出しは直列化されます。
つまり、1つのヘルパー、1つのdb接続が、Javaコードでシリアライズされているのです。 1スレッドでも1000スレッドでも、1つのヘルパーインスタンスを共有すれば、すべてのdbアクセスコードはシリアルになります。 そして人生は上々です(笑)
実際の異なる接続から同時にデータベースに書き込もうとすると、1つは失敗します。 最初の接続が完了するまで待って書き込みを行うことはありません。 単に変更を書き込まないだけです。 さらに悪いことに、正しいバージョンの insert/update を SQLiteDatabase 上で呼び出さないと、例外が発生しません。 LogCatにメッセージが表示されるだけで、それでおしまいです。
では、複数スレッド? 1 つのヘルパーを使用します。 以上です。 1つのスレッドしか書き込まないことが分かっている場合、複数のコネクションを使用することができ、読み込みが速くなる可能性があります。 でも、気をつけましょう。
このブログの記事には、より詳細な情報とアプリの例が掲載されています。
- Android Sqliteロック (2012/6/18リンク更新)
- Android-Database-Locking-Collisions-Example by touchlab GitHubにて
Grayと私は、彼のOrmliteをベースに、Androidのデータベース実装でネイティブに動作し、私がブログ記事で説明した安全な作成/呼び出し構造に従うORMツールを実際にラップアップしています。 これはもうすぐリリースされる予定です。 見てみてください。
一応、ブログのフォロー記事もあります。
によるフォークもチェックアウトしてください。 2ポイント0 を使用することができます。
関連
-
Android カスタムスピナーコントロールのドロップダウン・ボックスの実装
-
Android ProgressBarのスタイルカラーを変更する
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] AndroidのListViewで画像を遅延ロードする方法
-
[解決済み] ATTACHで開いたSQLiteデータベースファイルのテーブルを一覧表示するにはどうすればよいですか?
-
[解決済み] SQLiteでテーブルが存在するかどうかを確認するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[android studio]com.android.ide.common.process.ProcessException: aaptの実行に失敗しました
-
cygwinのダウンロード、インストールチュートリアル、およびCDTの「makeプログラムがパスに見つからない」バグの解消
-
android:EMSのプロパティ
-
エラー:未宣言の識別子(AS)の使用
-
Androidプロセス生存のためのソリューション
-
SpinnerのOnItemSelectedListenerのonItemSelectedメソッドの4つのパラメーターの意味
-
アンドロイドシェイプ、グラデーション、角丸、ボーダーラインの設定
-
超シンプルなアンドロイドのタイムディレイ機能
-
Android Studioのgitの使用とgitの設定パス
-
Android Studio http://schemas.android.com/apk/res/android 「URIが登録されていません」の解決方法について