Reputation: 21
I have an SQLite database, which receives some heavy use in my app. It is accessed from:
I call getWritableDatabase() once and use this everywhere. Each of the background processes uses an IMMEDIATE (i.e. non-locking) transaction, which speeds some of them up from minutes to seconds.
This all worked perfectly pre-Jellybean; the background processes had the speed benefit of the transaction, but this did not block Activites from loading data via ASyncTasks.
Post-Jellybean, each ASyncTask loading data for the GUI is blocked while a transaction is in progress, so often does not return for several seconds. This makes navigation slow and frustrating. I've isolated the blocking to the rawQuery database call.
I can't find any documentation which specifies exactly what changed in Jellybean, other than several methods being deprecated - http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#isDbLockedByOtherThreads() - with comments like "There is no longer the concept of a database lock, so this method always returns false."
Is there a simple way to mimic the pre-Jellybean behaviour?
Upvotes: 1
Views: 1026
Reputation: 21
I've found the solution to my own question. I'm still not sure exactly what Google have changed in Jellybean to stop what worked before working now - but the solution is to use enableWriteAheadLogging().
I had tried this before, to no avail - I was still getting blocked reads while a transaction was in progress. The important bit for me was (in the enableWriteAheadLogging() documentation)
If the database has any attached databases, then execution of queries in parallel is NOT possible.
Unfortunately, my application has two separate databases which are attached together to allow joined queries - enableWriteAheadLogging() returns false. I have prototyped removing the attachment, and this resolves the blocking issue; my select queries all run without delay while another thread runs an IMMEDATE transaction.
Sadly, I'll have to redesign my database schemas to implement a full fix.
Upvotes: 1
Reputation: 10673
It seems that pre-Jelly Bean async tasks were running in parallel all of the time. Now you've got an Executor under the covers running async tasks serially. Good news is, you can specify how your tasks run by branching based on OS version.
Read this article
Upvotes: 1