我似乎经常在我的代码(插件重)部分中得到上述错误。我知道通常这意味着连接中有一个打开的Cursor但我已经通过检查我的所有游标都在尝试finally块并关闭。 同样在logcat中错误读取'sqlite3_close(...)失败:5我认为这意味着数据库正忙?
如果我将以下代码添加到数据库连接关闭的finally块中,则可以“忽略”该错误。
finally
{
writer.endTransaction();
boolean successAtClose = false;
while(successAtClose == false)
{
try
{
writer.close();
successAtClose = true;
}
catch(Exception e)
{
e.printStackTrace();
}
}
dbConn.releaseLock();
}
当单步执行上面的代码时,'e.printStackTrace()'被击中一次,但在第二次尝试时,'writer.close()'不会抛出错误。
重申一下,这个问题甚至不会在每次代码块运行时发生,相同的数据可以插入5/6次,并且只会在其中一次上抛出错误。此外,错误不会在发生一次后立即重新发生,而是以随机间隔继续弹出。
有谁知道为什么会这样?还是比上面的最终代码更好的方法来恢复? (因为我需要很长时间才能将其添加到我的所有数据库代码中。)
增加:
使用自定义SQLiteOpenHelper
打开数据库,该自定义 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);
}
获取数据库访问权限如下:
Thread.sleep()
作为进一步的测试,我进一步在close()
之前但在endTransaction()
之后添加了对最终代码(在我的情况下为12秒)的{{1}}调用,这似乎是已经停止了错误并确认它不是打开游标的情况,但我宁愿不依赖于计时器。如果有更好的方法,也许预先检查数据库是否繁忙,请分享。
答案 0 :(得分:1)
如果您使用SQLiteStatement或SQLiteQuery对象来处理数据库,则需要确保它们也被关闭。如果它是SQLiteClosable你需要关闭它。
答案 1 :(得分:0)
这主要发生在你没有关闭光标时,意味着对数据库的某些引用是无效的。
引用链接Android SQLite Exception: unable to close due to unfinalised statements
答案 2 :(得分:0)
解决方法不正确。 close()
递减引用计数器,并且仅当计数器恰好为零时才是实际的资源处理,即尝试sqlite3_close()
。在第二次通话时,计数器将为负,呼叫将为无操作。
错误代码5为SQLITE_BUSY
。
现在要解决实际问题,请提供一些其他详细信息,例如如何打开和配置数据库以及如何开始交易。