Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓&;SQLite-偶然错误';由于未完成的报表';_Android_Sqlite - Fatal编程技术网

Android 安卓&;SQLite-偶然错误';由于未完成的报表';

Android 安卓&;SQLite-偶然错误';由于未完成的报表';,android,sqlite,Android,Sqlite,我似乎经常在代码的(插入量很大的)部分遇到上述错误。我知道这通常意味着连接中有一个打开的游标,但我已经检查了所有游标是否在try finally块中并已关闭。 同样在logcat中,错误读取'sqlite3_close(…)failed:5,我认为这意味着数据库正忙 如果我在数据库连接关闭的finally块中添加以下代码,则可以“忽略”该错误 finally { writer.endTransaction(); boolean successAtClose = false

我似乎经常在代码的(插入量很大的)部分遇到上述错误。我知道这通常意味着连接中有一个打开的游标,但我已经检查了所有游标是否在try finally块中并已关闭。 同样在logcat中,错误读取'sqlite3_close(…)failed: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
打开的,这个自定义的
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);
  }

作为进一步的测试,我进一步添加了对finally代码的
Thread.sleep()
调用(在我的例子中是12秒),在
close()
之前,但在
endTransaction()
之后,它似乎已经停止了错误,并确认这不是一个打开的游标,但我宁愿不依赖计时器。如果有更好的方法,可能是预先检查数据库是否忙,请共享。

这主要发生在您未关闭光标时,意味着对数据库的某些引用无效


请参阅此链接,解决方法不正确
close()
递减参考计数器,只有当计数器正好达到零时,才是实际的资源处置,即
sqlite3\u close()
尝试。在第二次呼叫时,计数器将为负值,呼叫将为禁止操作

错误代码5是
SQLITE\u BUSY
,这是正确的


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

如果使用SQLiteStatement或SQLiteQuery对象处理数据库,则需要确保它们也被关闭。如果它是SQLiteClosable,您需要关闭它。

正如我所说,我已经检查过了。如果是这样的话,不是每次代码运行时都会发生吗?上面的循环不会永远退出吗?我已经添加了更多的细节,但我认为我没有做任何特别的事情。你是说解决方案是错误的,因为即使第二次没有抛出异常,它仍然没有关闭?@user2145222解决方案中的
while
循环是无用的。不会引发异常,因为引用计数不完全为零,并且根本不会调用将引发异常的代码。更新后的问题代码中没有明显的错误,但您可以显示
getDatabaseAccess()
中的内容。添加了,但这只是设置了锁的基本代码(我也为上面的代码添加了释放锁调用,类似地,这只调用unlock())。如上所述,我在close()之前添加了一个thread.sleep错误也消失了。我猜我所做的插入次数意味着在调用close()时endTransaction()还没有完成。我已经做了更多的测试。我将坏while循环“fix”更改为while(writer.isOpen())。根据您在.close()中所说的幕后操作,我假设这将是无休止的循环(因为close失败一次后,它将永远不会再次运行,这意味着isOpen始终为true),或者它将运行一次(因为尽管失败,调用close仍会将此标志设置为false/closed),但与以前一样,它在第二次迭代中出现“忙”错误时退出。这是否意味着,如果关闭失败,因为它很忙,它会自己尽快关闭?毕竟,我很惭愧地说,一旦我经历了这一切,并把所有的东西都放在try finally块中,问题已经解决了。无论是什么样的声明被错过了,现在都在呼唤。我猜如果它看起来像只鸭子,嘎嘎叫起来像只鸭子……@user2145222我自己也去过那里。