SQLiteOpenHelper single connection vs multiple connections
Asked Answered
P

1

6

I am very much confused regarding access to SQLiteDatabase. Either it should be one connection or multiple connections to have access from multiple threads. I have read many articles including following two.

https://mcmap.net/q/63390/-how-can-i-avoid-concurrency-problems-when-using-sqlite-on-android http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking

Both of these recommends to have single connection. Even my own answer to same question was accepted by OP. I used the Singleton approach to access SQLiteopenHelper class.

https://mcmap.net/q/885084/-best-way-to-access-database-in-multi-threaded-application-android

But I am still confused after reading documentation of enableWriteAheadLogging which states

This method enables parallel execution of queries from multiple threads on the same database. It does this by opening multiple connections to the database and using a different database connection for each query. The database journal mode is also changed to enable writes to proceed concurrently with reads.

Now this is the confusing part. If I want to access database from simultaneous multiple threads, I have Singleton access to SQLiteOpenHelper which in my understanding means the serial execution of insertions while Simultaneous reads can be done with no-errors. But above documentation says, in order to have Simultaneous access, enableWriteAheadLogging should be called which in returns create multiple connections. What is this going on?? What does it mean if I do insertions by calling getWritableDatabase() using Singleton SQLiteOpenHelper from multiple threads? Will the calls be serial? Should enableWriteAheadLogging be called?

Please clarify.

Phone answered 15/1, 2018 at 14:46 Comment(1)
What is your usecase that you need SQLiteDatabase#enableWriteAheadLogging? The default (no write-ahead logging) blocks on "begin transacton" or "sql-insert/update/delete" further read/write threads until execution of the transacton has finished so this should be thread safe.Mittel
P
2

I would use the singleton instance whether I'm using enableWriteAheadLogging or not when dealing with threading which is the case in most apps unless it's a very trivial app like a sample.

Using a singleton instance is ensuring Thread Safety: The singleton instance ensures that synchronization works across that instance, that means when you have a read and write methods calling the database at the same time from different threads, one of them should wait for the other as the database gets locked while writing to it.

It's really clear that this is the case as written in the documentation and quoted below

it is not possible for reads and writes to occur on the database at the same time. Before modifying the database, the writer implicitly acquires an exclusive lock on the database which prevents readers from accessing the database until the write is completed.

enableWriteAheadLogging is actually altering the above behavior as the above statement is only true When write-ahead logging is not enabled (the default).

So what happens when you enable write-ahead logging through enableWriteAheadLogging?

It's actually changing the default behavior enabling actual parralism as it changes the underlying database journal file to enable doing a write and a read at the same time, but to do that it needs more memory than usual. Read the documentation quote below to know more!

In contrast, when write-ahead logging is enabled (by calling this method), write operations occur in a separate log file which allows reads to proceed concurrently. While a write is in progress, readers on other threads will perceive the state of the database as it was before the write began. When the write completes, readers on other threads will then perceive the new state of the database.

It is a good idea to enable write-ahead logging whenever a database will be concurrently accessed and modified by multiple threads at the same time. However, write-ahead logging uses significantly more memory than ordinary journaling because there are multiple connections to the same database. So if a database will only be used by a single thread, or if optimizing concurrency is not very important, then write-ahead logging should be disabled.

Pediatrics answered 15/1, 2018 at 15:30 Comment(2)
I am using Singleton, but my point is if I am using enableWriteAheadLogging and call getWritableDatabase from multiple threads at the same time, shouldn't this be a problem as there are multiple connections instead of single?Phone
Yes, there is no problem with that, this is handled internally by the database as there is a connection pool that is initiated when setting WAL #29063467Pediatrics

© 2022 - 2024 — McMap. All rights reserved.