2011-10-28 10 views
27

次のエラーが発生しています。では、データベースのロックを解除するにはどうすればいいですか?Androidデータベースがロックされています

10-28 08:43:26.510: ERROR/AndroidRuntime(881): FATAL EXCEPTION: Thread-11 
10-28 08:43:26.510: ERROR/AndroidRuntime(881): android.database.sqlite.SQLiteDatabaseLockedException: database is locked 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.database.sqlite.SQLiteDatabase.dbopen(Native Method) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:742) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at com.aa.me.vianet.dbAdapter.DbAdapter.open(DbAdapter.java:25) 
10-28 08:43:26.510: ERROR/AndroidRuntime(881):  at com.aa.me.vianet.services.NotificationManagerThread.run(NotificationManagerThread.java:49) 
+0

1.同じファイルでSQLiteOpenHelperを1つだけ使用していることを確認します。 2。一度に1つのスレッドのみがSQLiteDatabaseを使用していることを確認してください。 – Jens

答えて

32

私は、データベースを閉じるのを忘れてしまったと思います。あるいは、書き込みしようとしているときに別のスレッドがデータベースに書き込んでいると思います。 SQLiteは、別のエンティティが同じデータベースに同時に書き込もうとした場合に破損しないように、書き込み時にデータベースをロックします。アンドロイドは、のみログの猫にエラーが表示され、あなただけの忘れられます付属クエリ...だから

は、私がお勧め:

  • あなたは一つだけSQLOpenHelper
  • あなたからデータベースにアクセスします
  • endTransaction()を使ってトランザクションを終了させる場合は、正常に設定していない場合(つまり、ロールバックしたい場合など)は、トランザクションを使用する
  • OrmLiteを試してみることができますが、私は使っていませんが、他の人がそれについて賞賛していると聞いてきました。
+5

OrmLiteの元のポートをAndroidに書きました。あなたの最初の勧告は、1人のヘルパーだけを使用して、良いアドバイスです。あなたの第二のものはあなたの最初のものと矛盾します。 「データベース・ヘルパーのすべてのインスタンスを閉じる」とは、1以上を意味します。また、ヘルパー接続を閉じる必要もありません。私の答えを見てください。もともと、OrmLite用の複雑な参照カウントコードを書いて、ヘルパーを生きたままにしておき、終了したときに閉じるようにしましたが、Sqliteの "接続"は単なるファイルハンドルです。システムは、プロセスをダンプするときにそれらを閉じます。 –

+0

ちょっとケビン、これは本当にあなたのデータベースハンドラを閉じる必要はありませんか? –

+2

はい。私はそれが悪いと知っている。ハンドラは単なるファイルハンドルです。プロセスが終了すると終了します。 SQLite自体は壊れません。 logcatのエラーだけを表示するためには、それは "挿入"に当てはまりますが、他の方法には当てはまりません。そのため、常に「insertOrThrow」を呼び出す必要があります。 –

7

あなたが一度にオープンしているデータベース(これは、データベースを変更する際に競合状態を防ぐためです)への接続を1つ持つことができますので、これが起こっている理由があります。私はあなたのデータベースへの接続を別のスレッドから複数回推測していますか?これを回避する最も簡単な方法は、データベースのフロントエンドをContentProviderにするだけです。これにより、複数のスレッドからのクエリを処理できます。

詳細については、blogpostをご覧ください。

+0

blogpostのリンクが壊れている、新しいリンクhttp://www.touchlab.co/blog/android-sqlite-locking/ – pengwang

+0

がもう一度壊れています。 – christophercotton

+0

@christophercottonもう一度私のために働いているようです。 –

11

アプリ全体で1つの接続を使用します。ここを参照してください:

http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection

+0

このリンクを修正できますか?単一の接続でマルチスレッドアクセスを扱うにはどうすればいいですか? – Michael

+0

@Michael Fixedリンク! –

+0

私はこの方法を使用しましたが、私の場合、私の質問を見てください[link is here ...](http://stackoverflow.com/questions/13859840/application-crashes-on-installation -with-error-sqlite3-exec-failed-set-sync) – MobileEvangelist

0

私は、同様のエラーが発生しました。私の問題は、誤って2つのヘルパークラスのデータベースに同じ名前を与えたため、同じデータベースに同時にアクセスすることになりました。したがって、複数のヘルパークラスを持つ単一のデータベースにアクセスしていないことを確認してください。

2

私は同じ問題を抱えていた、この

db.beginTransactionNonExclusive(); 
    try { 
     //do some insertions or whatever you need 
     db.setTransactionSuccessful(); 
    } finally { 
     db.endTransaction(); 
    } 

を使用してみてください、私は経由して自分のデータベースにアクセスしようとしていたと私は同じ問題を抱えていた私はdb.beginTransactionと試みたが、それは、BDに

0

をロックContentResolver私は既に直接取引をするために必要なSQLiteDatabaseの接続を開いていました。

私の直接のSQLiteDatabase接続が開かれる前にContentResolverのものが完了するように、自分のコードの順番を変更して解決しました。

私もコードを削除しましたので、私は直接私の直接SQLiteDatabaseを閉じません。

this answerと読む価値があります。他にも参考になるものがたくさんあります。

関連する問題