web-dev-qa-db-ja.com

Sqliteデータベースインスタンスはスレッドセーフです

いくつかのテーブルを持つデータベースがあります。複数のスレッドを使用してテーブルを更新したい。すべてのスレッドでSQLiteDatabaseの同じインスタンスを使用します。

このアプローチが正しいかどうかを提案してください。 Sqliteデータベースはスレッドセーフですか? 2つの異なるスレッドが、異なる値のセットの同じテーブルを同時に更新できますか。

31
Manish

[間違い:]いいえ、デフォルトではスレッドセーフではありません。ロック関連のSQLiteHelperメソッドを使用して、スレッドセーフを提供する必要があります。

[EDIT]:SQLiteDatabaseクラスは、デフォルトでロックメカニズムを提供します(参照コメント)、マルチスレッドで実行している場合は、スレッドセーフにするために何かを変更することを検討する必要はありません。

このドキュメントで「スレッド」を検索: http://developer.Android.com/reference/Android/database/sqlite/SQLiteDatabase.html

そして続きを読む:

27
AhmetB - Google

AndroidはJavaロックメカニズムを使用して、SQLiteデータベースアクセスのシリアル化を維持します。したがって、複数のスレッドが1つのdbインスタンスを持っている場合、常にシリアル化された方法でデータベースを呼び出しますそしてもちろんデータベースはスレッドセーフです

シングルスレッドからデータベースを使用していることを確認した場合、setLockingEnable(false)を呼び出すことによってデータベースの内部ロックを無効に設定するオプションがありましたが、このメソッドはAPIレベル16から 非推奨 を取得し、使用されなくなりました。このメソッドの実装がSQLiteDatabaseクラスにある場合、そこには何も記述されていません。つまり、空のメソッドです。

_public void setLockingEnabled (boolean lockingEnabled)
_

このメソッドは何もしません。使用しないでください。

注意が必要なことの1つは、ヘルパークラスのインスタンスを1つ(つまり、シングルトンにする)作成し、同じインスタンスを複数のスレッドで共有し、操作の合間にデータベースでclose()を呼び出さないことです。そうしないと、次の例外が発生する可能性があります。

_Java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase_

そのため、データベースへのアクセスの間にdatabase.close()を呼び出さないでください。すべての操作が完了すると、データベースは内部的に閉じる操作を実行します。

5

setLockingEnabled を使用すると、データベースがスレッドセーフかどうかを制御できます。

クリティカルセクションを囲むロックを使用して、SQLiteDatabaseをスレッドセーフにするかどうかを制御します。これは非常にコストがかかるため、DBが単一のスレッドでのみ使用されることがわかっている場合は、これをfalseに設定する必要があります。デフォルトはtrueです

だから私はこれがあなたの質問に答えると思います。

メソッドsetLockingEnabledはAPIレベル16で廃止されました

2
Mojo Risin