Android& SQLite - 由于未完成的语句而无法关闭的偶然错误

时间:2013-10-28 12:46:34

标签: android sqlite

我似乎经常在我的代码(插件重)部分中得到上述错误。我知道通常这意味着连接中有一个打开的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}}调用,这似乎是已经停止了错误并确认它不是打开游标的情况,但我宁愿不依赖于计时器。如果有更好的方法,也许预先检查数据库是否繁忙,请分享。

3 个答案:

答案 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

现在要解决实际问题,请提供一些其他详细信息,例如如何打开和配置数据库以及如何开始交易。