Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid & SQLite - Occasional error 'unable to close due to unfinalised statements'
    text
    copied!<p>I seem to get the above error every so often in (an insert heavy) part of my code. I know normally this means there is an open Cursor within the connection but I have been through checking all my cursors are in try finally blocks and closed. Also in logcat the error reads 'sqlite3_close(...) failed: 5 which I think means the database is busy?</p> <p>The error can be 'ignored' if I add the following code to my finally block where the database connection is closed.</p> <pre><code> finally { writer.endTransaction(); boolean successAtClose = false; while(successAtClose == false) { try { writer.close(); successAtClose = true; } catch(Exception e) { e.printStackTrace(); } } dbConn.releaseLock(); } </code></pre> <p>When stepping through the code above the 'e.printStackTrace()' is hit once but on the second attempt the 'writer.close()' does not throw an error.</p> <p>Just to reiterate, this problem doesn't even happen every time the code block runs, the same data can be inserted say 5/6 times and only throw the error on one of these times. In addition the error does not reoccur straight away after happening once but continues to pop-up at random intervals.</p> <p>Does anyone know why this might occur? Or a better way to recover from this than the finally code above? (Since it will take me a long time to add this to all my database code.)</p> <p>ADDED:</p> <p>Database is opened with a custom <code>SQLiteOpenHelper</code> which is extended to use a reentrant lock to ensure only one thread accesses the database at any one time. So the start of the code is like:</p> <pre><code> MyDatabaseHelper dbConn = MyDatabaseHelper.getDatabaseAccess(c);//await availability/lock the database here SQLiteDatabase writer = dbConn.getWritableDatabase(); try { writer.beginTransaction(); //do inserts writer.setTransactionSuccessful(); </code></pre> <p>Get database access as follows:</p> <pre><code> public static MyDatabaseHelper getDatabaseAccess(Context c) { l.lock(); return new MyDatabaseHelper(c); } </code></pre> <p>As a further test I have further added a <code>Thread.sleep()</code> call to the finally code (in my case of 12 seconds), before the <code>close()</code> but after the <code>endTransaction()</code>, that seems to have stopped the error and confirm it is not a case of an open cursor, but I would rather not rely on a timer. If there is a better way, perhaps to pre-check whether the database is busy, please share.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload