私のコードの(挿入が重い)部分で、上記のエラーが頻繁に発生するようです。通常、これは接続内に開いているカーソルがあることを意味しますが、すべてのカーソルが try finally ブロックにあり、閉じられていることを確認しました。また、logcat では、'sqlite3_close(...) failed: 5 というエラーが表示されます。これは、データベースがビジーであることを意味すると思いますか?
データベース接続が閉じられている最終ブロックに次のコードを追加すると、エラーを「無視」できます。
finally
{
writer.endTransaction();
boolean successAtClose = false;
while(successAtClose == false)
{
try
{
writer.close();
successAtClose = true;
}
catch(Exception e)
{
e.printStackTrace();
}
}
dbConn.releaseLock();
}
上記のコードをステップ実行すると、「e.printStackTrace()」が 1 回ヒットしますが、2 回目の試行では「writer.close()」はエラーをスローしません。
繰り返しますが、この問題はコード ブロックが実行されるたびに発生するわけではなく、同じデータが 5/6 回挿入され、そのうちの 1 回でのみエラーがスローされる可能性があります。さらに、エラーは一度発生してもすぐには再発せず、ランダムな間隔でポップアップし続けます。
なぜこれが起こるのか誰にも分かりますか?または、上記の最終的なコードよりも、これから回復するためのより良い方法はありますか? (これをすべてのデータベース コードに追加するには長い時間がかかるためです。)
追加した:
SQLiteOpenHelper
データベースは、一度に 1 つのスレッドのみがデータベースにアクセスするように再入可能ロックを使用するように拡張されたカスタムで開かれます。したがって、コードの開始は次のようになります。
MyDatabaseHelper dbConn = MyDatabaseHelper.getDatabaseAccess(c);//await availability/lock the database here
SQLiteDatabase writer = dbConn.getWritableDatabase();
try
{
writer.beginTransaction();
//do inserts
writer.setTransactionSuccessful();
次のようにデータベース アクセスを取得します。
public static MyDatabaseHelper getDatabaseAccess(Context c)
{
l.lock();
return new MyDatabaseHelper(c);
}
さらなるテストとして、finally コードへの呼び出しをさらに追加しました(Thread.sleep()
私の場合は 12 秒) close()
。endTransaction()
むしろタイマーに頼らないでください。データベースがビジーかどうかを事前に確認するためのより良い方法がある場合は、共有してください。