2011-07-13 19 views
28

私はいくつかのテーブルを持つデータベースを持っています。 複数のスレッドを使用してテーブルを更新したいとします。 すべてのスレッドでSQLiteDatabaseの同じインスタンスを使用します。Sqliteデータベースインスタンスのスレッドセーフです

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

+0

[AndroidのSQLiteのベストプラクティスは何ですか](http://stackoverflow.com/questions/2493331/what-are-the-best-practices-for-sqlite-on-android) –

+0

https://stackoverflow.com/questions/12758655/sqlitedatabase-multi-thread-locking-pattern –

答えて

23

[誤:]いいえ、デフォルトではスレッドセーフではありません。ロック関連のSQLiteHelperメソッドを使用して、スレッドの安全性を確保します。

[EDIT]: SQLiteDatabaseクラスは(コメントを参照)、デフォルトでロック機構を提供し、マルチスレッド上で実行されている場合、あなたはスレッド安全性を持っているために何かを変更することを検討する必要はありません。

この文書の 'スレッド' の検索:http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

そして続きを読む上:

+11

http://edveloper.android.com/reference/android/database/sqlite/SQLiteDatabase.htmlに記載されているように、ロックを使用する必要があります。 #setLockingEnabled%28boolean%29 'クリティカルセクションの周りのロックを使用してSQLiteDatabaseをスレッドセーフにするかどうかを制御します。これは非常に高価なので、DBが1つのスレッドだけで使用されることがわかっている場合は、これをfalseに設定する必要があります。デフォルトはtrue'です...これはデフォルトではスレッドセーフですか? – Ryan

+1

Hmm。それは間違っているはずです。うーん。 –

+1

"このメソッドはAPIレベル16では廃止されました。 このメソッドは現在何もしません。使用しないでください。" –

-2

..

setLockingEnabled(ブール値がlockingEnabled)SQLiteDatabaseはスレッドセーフ周りのクリティカルセクションをロックを使用して作られているかどうかを コントロール。

2

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

クリティカルセクションの周りのロックを使用してSQLiteDatabaseをスレッドセーフにするかどうかを制御します。これは非常に高価なので、DBが1つのスレッドだけで使用されることがわかっている場合は、これをfalseに設定する必要があります。デフォルトはtrueです

これはあなたの質問に答えると思います。

AndroidはシリアライズSQLiteのデータベースへのアクセスを維持するためにJavaのロック機構を使用して16

+4

api 16で非推奨 –

3

APIレベルで減価償却されるsetLockingEnabled方法。したがって、複数のスレッドが1つのdbインスタンスを持つ場合、常にデータベースにシリアル化された方法で呼び出します。もちろん、データベースはスレッドセーフですです。

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

public void setLockingEnabled (boolean lockingEnabled) 

このメソッドは現在何もしません。使ってはいけません。

私たちが注意しなければならないことは、ヘルパークラスのインスタンスを1つ(つまりシングルトンにして)作成し、同じインスタンスを複数のスレッドに共有し、操作の間にデータベース上でclose()を呼び出しないことです。データベースへのアクセスの間でdatabase.close()を呼び出すことはありません、すべての操作が終了になりますと、データベースが自己の内部でクローズ操作を実行しますので、

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

:次の例外を得ることができます。

関連する問題