Android accessing SQLite Database from multiple threads - android

I have a SQLite Database in android that is accessed from a thread when the activity is running, and in the onPause() of the activity a new thread is created to save everything into the database with a different thread to avoid timeout issues. However, when I try to do so, I either get database is locked errors. How can I fix this? Since I need to access the database from a separate thread in onPause(), could I delete somehow my previous access to it since I wouldn't use it again?

You cannot access an SQLite database when it already has a lock on it.
To avoid this, Android gives you ContentProviders to handle this sort of thing.
You should implement your own ContentProvider to do this kind of thing.
That said, databases can NEVER be assumed to be threadsafe unless you manage the threads yourself. Avoid using the db like this. Instead, cache the data (on a stack, perhaps) and request access to the database with a callback when your current transaction is complete.

As far as I know SQLite does not support concurrent access, so you either have to have a dedicated thread to provide access, or you have to obtain a lock to the SQLite object instance.

Related

How to Execute threads in parallel and insert corresponding data in sqlite database without database lock?

I need to call multiple api's each executing in separate thread and insert the respective data from response to sqlite database without causing locks. Can anyone help me in this regard with a working example that I can refer to.
I need to call multiple api's each executing in separate thread and insert the respective data from response to sqlite database without causing locks.
You don't need to do anything special. Multiple threads can make use of the same SQLiteDatabase object without you doing locking at the application level. Sqlite does it's own locking under the covers. You should never get deadlocks but one thread will have to wait for the other thread to finish making its insert.
See these questions/answers:
Can two AsyncTasks share the same SQLiteDatabase object?
What are the best practices for SQLite on Android?
Sqlite under Android is single threaded. Even if multiple threads were using the same database connection, my understanding is that they would be blocked from running concurrently. There is no way to get around this limitation. If you open two connections to the same database, this would corrupt the database because database updates would not be coordinated.

Android SQLite : Lock + access from multiple threads

I am trying to understand the possible ways to work with SQLite when there can be multiple threads work on DB.
Based on various responses in stackoverflow and other sites, it appears that there will be locking issue when same sqlitehelper instance is used from multiple threads. In a typical java application, I would expect instance to mean single object of type sqlite helper to be used by different threads of application.In such cases, the locks ,I guess, are a matter of correctly using the synchronized blocks. [Correct me here as I am not comfortable with this way of looking at sqliethelper instance here]
My concern is with sharing same data base : when one instantiate sqlite helper in different threads [ie each thread has its own object instance] but working on same Database [this I guess is more inline with having same db instance].
In such cases I'm getting frequent database lock errors. This occurs even when the threads are working on different tables of database.
In my application database can be updated by user interaction through application or by getting data through server [periodic synchronization]. And some time when synchronization process and user activity overlaps, I get the lock issues. As this pattern of data processing seems to be common in application synchronizing with server, would like to know how do lock issue due the concurrency is to be handled.
I would like to understand this since if this is bound to happen always then probably need to make only one handler over database and implement queue over that to avoid lock. But that will mean the complete application needs to be aware that the database may not get updated immediately and they need to implement listener to know when the data is actually updated in database.
thanks
pradeep
As far as I know sqlite is intended for single process usage. No matter what you will always need to access the database from one thread at a time. You can do selects from multiple clients but can only write from one at a time. And other readers and writers will ahve to lock in the mean time.
As a side note - database access can hardly ever be considered instantaneous.

Android SQLite connection management

I'm working with SQLite in my android project. There is a feature that is clear to me -- if there are multiple threads working with DB then they should use only ONE instance of DBHelper and SQLite guarantee a safe access (even if it is concurrent) to the DB.
But I still have one thing needed to be clarified. How should I manage with DB connection (SQLiteDatabase object)? How often should I call geWritableDatabase() and close()? Is it ok if I call these methods once? Or it's better to obtain SQLDatabase object and close one every time I perform read/write operation on DB?
It is handled by default... I mean if a writtable database open, whenever you try to access read-only database it closes writtable one and create new read-only database instance. As far as i know :)

AsyncTask accessing Database - Where to initialize, close?

When accessing a database within an AsyncTask, should the database connection be a member of the parent Activity or opened/closed within each AsyncTask?
If the connection is a member of the activity, I'm concerned that when switching between my application's activities there is the possibility that the database connection could be closed before the AsyncTask utilizing it has completed.
Not something I've ever really thought about but instinctively I'd make the AsyncTask as self-contained as possible, i.e., have it handle its own db operations internally. The same applies to any threaded code.
EDIT: Here's a link to a good article discussing multiple access to SQLite in Android...Android SQLite Locking

Closing an SQLite database on one thread breaks the database opened on another thread

We all learn that resources, such as database connections, should be acquired late and released early.
Yet applying this principle to SQLite database connections on Android have caused me some headache.
I have an app that download updates from a backend server in a service working in the background, writing updates to the database at a regular basis. The problem I experience arise when the following sequence occurs:
Service opens a writable database connection
Some activity opens a readable database connection
Service closes its database connection concurrently with the activity reading data
Activity fails due to its database connection was closed
Both the service and the activity uses the same SQLiteOpenHelper class, though different instances, to open their connections. My initial assumption was that this should work just fine, but somehow it seems that the underlying connection is shared between the two database instances.
To work around the problem I ended up not closing the database objects, only closing any opened cursors. This seems to work, though I'm not sure that I'm not leaking memory here.
Is there something obvious I am missing here?
Is there something obvious I am missing here?
I'd say no. Looking at the source code to SQLiteOpenHelper, I can't see how two instances could be sharing a SQLiteDatabase object.
Some diagnostic suggestions:
Dump the toString() value of each SQLiteDatabase, which should give you a Java instance ID. If they are the same, that is where your problem lies, and you will need to work your way upstream to figure out how the heck this is happening (e.g., you really are using the same instance of the SQLiteOpenHelper).
With your database in a stable state (i.e., no need to create or upgrade), flip one of your two database spots to use SQLiteDatabase directly, rather than via SQLiteOpenHelper, and see if that changes matters.

Categories

Resources