Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What about multithreading in Android SQLite?

In my app I've got to implement some UI and Sync service. It runs in the background and updates data. Sync service is not very simple, it uses multithreading.

So, here is my story: When I started developing this app I didn't know anything about sqlite, so I just didn't use any thread synchronization in Java. Result: I got many Exceptions like "SQLiteException: database is locked: BEGIN EXCLUSIVE;"

Then I synchronized all my transactions with regular Java synchronized () {} block. Everything got much better. But I used Cursors for implementing CursorAdapter for my lists. So, sometimes I was getting the same "SQLiteException: database is locked: BEGIN EXCLUSIVE;"

I ended creating a small thread safe sqlite utility which handles all that thread-safe stuff. Also I've got to use something like ArrayAdapter (read all data from Cursor and close it after reading, also synchronize this block) for my UI. So, it is working OK

But, I don't like such way to handle UI, cause UI got really slower with this solution - reading some amount of data from cursor is rather fast, but is slower than using CursorAdapter

So, who got the solution for this question? Thank you

like image 905
Eugene Nacu Avatar asked Apr 07 '11 06:04

Eugene Nacu


2 Answers

SQLite implements a exclusive write lock, shared read lock model. This means that you can have concurrent readers active in the database at the same time or a single writer, you can't have both. If you use the WAL logging feature you can have a single writer and multiple readers active in the database at the same time, but you still can't have more than one writer. There is excellent documentation on SQLite concurrency here and here.

You might want to consider taking a look at Berkeley DB. Berkeley DB offers a SQL API that is completely compatible with SQLite. If fact, what we've done is to add the SQLite parser, planner and executor on top of the Berkeley DB storage layer. What this provides to the SQLite application developer is a SQLite-compatible library that has additional scalability, concurrency and reliability (HA), as well as other features. Berkeley DB supports multiple readers and writes concurrently accessing the database. There are two excellent white papers written by Mike Owens, author of "The Definitive Guide to SQLite" that compare Berkeley DB and SQLite (Performance comparison, Behavioral Differences).

Disclaimer: I'm one of the product managers for Berkeley DB, so I'm a little biased. But requests like yours (need more concurrency, scalability, reliability from SQLite) is exactly why we decided to provide a combined library that gives you the best of both worlds.

like image 50
dsegleau Avatar answered Sep 20 '22 23:09

dsegleau


So, finally came out to the solution. Here it is.

I read some forums, google groups and found out that sqlite database should be opened only once. So, I implemented this using singleton.

Also, I implemented some db code to synchronize all write operations (to prevent many threads execute write operations at one time). And I don't care about opening cursors, reading from them.

After some days testing I've got no error reports from my users, so I think this works

In my previous work I opened sqlite database many times across the application, that was the problem.

like image 21
Eugene Nacu Avatar answered Sep 20 '22 23:09

Eugene Nacu