I am having an issue while upgrading an app to support Android Lollipop. The app implements a SyncAdapter that writes on a db through a content provider. At the same time it can happen that the user is browsing the front-end of the app where loaders read the same data from the database. Loaders also listen to data changes.
Now, if I run the program on a pre-Lollipop device everything works without any error output.
On Lollipop instead I receive the following logcat message:
11:20:59.344 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850 11:20:59.364 22341-22376/com.example.com E/SQLiteLog﹕ (10) POSIX Error : 11 SQLite Error : 3850
Now, from SQLite docs:
(3850) SQLITE_IOERR_LOCK
The SQLITE_IOERR_LOCK error code is an extended error code for SQLITE_IOERR indicating an I/O error in the advisory file locking logic. Usually an SQLITE_IOERR_LOCK error indicates a problem obtaining a PENDING lock. However it can also indicate miscellaneous locking errors on some of the specialized VFSes used on Macs. Everything seems to work properly on a high level (that is both reads and writes are performed)
and:
A PENDING lock means that the process holding the lock wants to write to the database as soon as possible and is just waiting on all current SHARED locks to clear so that it can get an EXCLUSIVE lock. No new SHARED locks are permitted against the database if a PENDING lock is active, though existing SHARED locks are allowed to continue.
I know that the SQLite version has been updated by few major releases in Lollipop, so I am prone to think that the error is due to some new behaviour of SQLite that I cannot isolate.
However, everything seems to work fine from a higher level point of view (App doesn't crash, both reads and writes are performed, framerate doesn't drop - at least to human eyes) but I wouldn't want to ignore the issue to release the app until I am sure it won't cause data corruption or troubles.
Perhaps I am missing on some important changes to lollipop regarding locks and multiprocess database access, but I feel it's an issue that lies on a lower level with respect to the Art/Dalvik domain and so has to be fixed in an NDK context.
Is there a way to fix this possibly without distributing an app specific version of SQLite? Is there any manifest/SQLite option to avoid the error?
Thanks in advance
Writer locks the database for both reading and writing. That means it has to wait for all readers to finish and release locks in order to obtain lock.
After the writer requested a lock, new reader locks must wait for writer to first obtain lock and then release it.
This could be a solution for you: WAL mode
Activating And Configuring WAL Mode:
An SQLite database connection defaults to journal_mode=DELETE. To convert to WAL mode, use the following pragma:
PRAGMA journal_mode=WAL;
WAL will not block readers while writing, which means also that writer does not need to wait for current read locks to be released.
Minimum SQLite version required for WAL is 3.7.0 (2010-07-21). Lollipop 5.0 uses SQLite 3.8.4.3 so WAL should be available for you.
But WAL does not exist in Android version less than 3.0 although there are some exceptions from this. Take a look at Version of SQLite used in Android?. If you don't need your app to work below Android 3.0 you can use WAL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With