Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it essential to close the database?

Tags:

android

sqlite

In Google's Notepad Example, they don't seem to close the database, at least not in onDestroy().

What is the purpose of closing it, and do I really need to? Does an open database take up significant memory? I have found that closing it in onDestroy leaves vulnerabilities if there are any threads running that might try to access it after the Activity is finished.

like image 282
Tenfour04 Avatar asked Feb 11 '11 17:02

Tenfour04


People also ask

Is DB Close necessary?

Because key/data pairs are cached in memory, applications should make a point to always either close database handles or sync their data to disk (using the DB->sync() method) before exiting, to ensure that any data cached in main memory are reflected in the underlying file system.

What happens if you don't close database?

It will stay open in memory, clogging that address until the system times it out and closes it. There was a time that this was a real problem even on small websites. People would open a connection, and it would stay open for weeks. As more users hit that same page, more and more connections would open.

Why is it important that we support closing the database connection?

If you do not close your database connections, many problems can occur like web pages hanging, slow page loads, and more. Think of it as going through a door to your house. Maybe the door will shut by itself, but maybe it won't.

What happens when a database is closed?

Closing a database causes it to become unusable until it is opened again. It is recommended that you close any open cursors before closing your database. Active cursors during a database close can cause unexpected results, especially if any of those cursors are writing to the database.


1 Answers

If you don't close the database connections, they'll cause memory leaks over time.

The Notepad example does use startManagingCursor, but you still need to explicitly close the db connection. Run the Notepad example as-is and edit several notes in succession, you'll see that it starts throwing Warnings and Errors in LogCat. (In larger applications, you'll also start to see Memory Leak Detection warnings.)

W/SQLiteCompiledSql(  302): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: INSERT INTO notes(body, title) VALUES(?, ?);
W/SQLiteCompiledSql(  302): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
W/SQLiteCompiledSql(  302):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
...
W/SQLiteCompiledSql(  302):     at dalvik.system.NativeStart.main(Native Method)
E/Database(  302): close() was never explicitly called on database '/data/data/com.android.demo.notepad3/databases/data' 
E/Database(  302): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
E/Database(  302):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
...
E/Database(  302):  at dalvik.system.NativeStart.main(Native Method)

You mentioned that closing it in onDestroy() "leaves vulnerabilities" in any non-UI threads that are still running. If you're using AsyncTask, you can check the status of of these threads using getStatus on your tasks.

if ( myAsyncTask.getStatus() == AsyncTask.Status.FINISHED ){
    mDbHelper.close();
}

Then close the connection in the onPostExecute method of your AsyncTask.

Hope that helps...

like image 175
Farray Avatar answered Oct 14 '22 10:10

Farray