I need to write some application which will have a couple threads and these threads will be work with local database. I afraid that these threads will be compete among themselves for database. Is there any simple solution to solve this problem? I read that I can use content provider becouse then will be only one connection with database but maybe there is another solution? Thanks for all advice and tip.
Use one DataBase Helper class and create a single instance which can be accessed by both threads.
Make all the methods in DataBase Helper class as synchronized to avoid race conditions.
Related
I have a problem with my database.
Basically my applications read texts and rates of text from my SQLite database and show it on screen. I have also Thread function which downloads content from external internet server and uploads it into the database.
On less popular devices (mostly tablets) it generates errors like:
DB close exception
DB locked
Someone advised me to create something called a singleton to handle this and I created it but it generates errors. So I have an idea to use AsyncTask instead of Thread; do you think it will help?
Maybe you have other solutions?
AsyncTask will not help you here. You have to create a database connection as a singleton.
You should get a readable database for when you are reading and a writable database for when you are writing. Then you will be able to do both at the same time.
Both of the methods are in the SQLHelper class
Never close the DB. Make sure you have only one Helper instance per application.
See this for reference SQLiteDatabase close() function causing NullPointerException when multiple threads
This may help you :)
There have been a few questions on this topic but none giving firm reasons for why there should or shouldn't be a single or multiple instances of the databaseHelper.
When is it a good idea to have multiple instances of DatabaseHelper and when is it not. Is less complexity (if that is actually the case ) a good enough reason to have just a single instance ?
Your DatabaseHelper should be a singleton for sure. Each helper maintains the single connection to the database. If you have multiple helpers with connections to the same database, then concurrency issues will result. Sqlite does it's own locking underneath the single connection to ensure proper concurrent access to the database so using that single connection (and therefore that single helper) for all of your database operations is recommended and required.
Use one DatabaseHelper for each database in the application. SQLite takes care of file locking for you (many reads, only one write) and Android using Java locking in SQLiteDatabase. However, you can still get have a concurrency failure (simulataneous connections writing at once). It's the multiple connnections part that you want to avoid and that is what is managed by one instance of the DatabaseHelper.
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.
I have a an application that has 2 parts.
A service which creates content.
An application that uses the content
Each of these run as different processes. The problem is that both of them share a database. And I frequently get database locked error, both when the service tries to write something and the UI is reading data. Also vice versa.
How do go about this?
The class used to access DB is a singleton class. But since both UI & the service are 2 different processes, there are 2 singletons I presume. So that doesn't help.
Even synchronise won't help I suppose, since again because of 2 different processes.
Content Providers maybe an option, but since I use complex queries to dig info, it would be really hard to use that too.
How do I get the two processes share the database.
Any cues would be greatly appreciated.
Using a content provider is one option. Another is to take a look at Berkeley DB. The BDB SQL API is SQLite compatible and the BDB lock manager allows multiple threads and/or processes to read/write to the database concurrently.
close the connection after each operation
catch the database locked error and try to reconnect after 50ms
or let the service handle the database and the activity ask the service for data
may be there is isDatabaseInUseMethod ?
You should use a content provider to funnel your database queries through one source. Inside of the content provider you can use any locking mechanisms you would like to ensure you're not having concurrent access. You may also think about using content observers to coordinate service actions with changes to the database.
The following is a great article on how locking works with SQLite on Android and what things to be aware of: http://kagii.squarespace.com/journal/2010/9/10/android-sqlite-locking.html
I would think you'll find some answers there :)
I have a (hopefully) quick question regarding handling SQLite database connections in Android. I have an app that is composed, naturally, of several activities. I have no trouble creating/updating/querying the database, as I've created a single, dedicated class to handle that work via SQLiteOpenHelper, etc.
My question is this: since these activities all share this same database, is this usually implemented as a single, static member, or should each activity own its own connection? My concern of course is the cost of re-connecting to the database in each activity.
Or, put another way, is there any reason not to just store a singleton instance?
I'm also wondering if there's something going on behind the scenes similar to .NET's connection pooling to reduce the cost of opening connections.
Thanks in advance!
Connection opening in SQLite is about 0.2ms.
The best practice tells us to open and close the connection each time we need one.
Just use SQLiteOpenHelper.getReadableDatabase() and SQLiteOpenHelper.getWriteableDatabase() - Android will manage and cache the connection so you don't need to.
In fact, refer to the official Google Using Databases documentation:
To write to and read from the
database, call getWritableDatabase()
and getReadableDatabase(),
respectively. These both return a
SQLiteDatabase