Android sqlite concurrency without exceptions - android

Sqlite on android lets you access the database from multiple procs for reads, but if you're currently writing from one process, reads and writes from other procs will throw an exception because the first write has a lock on the db.
By "procs" I mean other threads in the same app.
Is there a standard way to have the other threads simply wait until the database is available again, possibly with a specified timeout, rather than throwing an exception?
Anticipating the "why are you doing it that way?" answers, its just the way we're doing it, and that's it. We're also not going to use a content provider. Just want a way to synchronize db access.
Assuming there's no standard way to do it, we'll probably wind up writing a wrapper around the db calls to do some thread synchronization.

So long as you're using the same SQLiteDatabase object, the synchronisation is done for you.
So if you access the object via a singleton, there should be no problem. Though you may want to add some further logic if you want to implement a timeout, e.g. wait/notify or something similar.

Or you can use another database that does support it, like H2. I know it may sound like a strange idea. But according to my initial test it works well (on the emulator as well as on the device), and is actually not slower. Except for opening and closing a database, which is currently quite slow, about 1 second, but that has other reasons, and hopefully will get fixed in the next version.

Related

Making a checkpoint of SQLITE database in WAL mode after each insert/update/delete operation

I have SQLITE database inside my Xamarin Android app and I need to be able to read and write from it concurrently from different threads and/or processes. So I'm trying now to use it in WAL mode. It works fine mostly. SQLITE_BUSY errors which I experienced before not occur anymore.
The problem is that I also would like to be able to take this database off the device (i.e., send by email) - preferably, in one file.
In WAL mode I have the main database file x.db3 along with x.db3-wal and x.db3-shm, which is not good enough for this purpose.
Theerefore y idea was to execute pragma checkpoint(passive) after each insert, update or delete operation so the database will actually almost always consist from one file. Updates are rare in my case, so performance hit is probably not an issue. I understand that during checkpoint the readers will not be able to read the data and I can handle it.
But anyway my intuition tells me that this is not a right way to use WAL logging and that's why I'm asking. It "looks" to me like abuse.
I'd appreciate any ideas about problems I may run into with this approach.

what are the advantages of using a ContentProvider over normal SQLIte storage?

I want to share data across multiple applications, instead of having a ContentResolver->ContentProvider mechanism, I can just define a client library which talks to the process which does the SQLite DB operations right?
What does the ContentProvider brings in here which we cannot achieve by having a Process expose the data?
You can find answer Exact Difference between “Content-Provider” and “SQLite Database”.
But I like to explain this..
What does the ContentProvider brings in here which we cannot achieve by have a Process expose the data?
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.
Also It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
You can check the thread below:
Exact Difference between "Content-Provider" and "SQLite Database"

What's the better method to store Android app's data -- in SQLite or on the file system?

My app needs to store data on the phone, but I'm not sure what's the more efficient method. I don't need to search through the data or anything like that. I just need to be able to save the app's current state when it closes and restore when it's back up. There is between 1mb and 10mb worth of data that will need saving.
There are basically a bunch of custom classes with data in them, and right now I have them as Serializable, and just save each class to a file. Is there any reason for me to change that to store it in SQLite?
If you where to use sqlite you could save as you go, and know that whats in the DB is pretty much uptodate if the app/activity holding the data is suddenly killed by the os. Other that that I cant see and obvious reason to use sqlite for your use-case.
Also for the sql approach you have a clear cut way to change the structure of your domain objects at a later time and to migrate the data from a old to a new version of your database. This can be done using serialized objects as-well, but then the objects needs to be duplicated, both new and old at the same time. And that to me sounds very very scary and messy, especially considering that you might need to go from version x to y, so you might end up with some pretty tricky problems if you ever need to update the domain objects.
And I can honestly not see any benefits of using the flat-file/serialized approach.
You mention in your question that the data is only meant to save the state of the app, therefore my initial response would be to keep it on the devices especially since you mention that the file size would not be much more than 10MB, which is quite reasonable.
So my answer to you would be to keep it as is on the device. If your usage of the information changes in the future, you should then reconsider this approach, but for now it's totally logical.
If you're only saving serialized classes, you could use an ORM mapper as discussed in this thread . This saves you the inconvenience of writing your own mapper and is easily extendable to new classes. Also, if your requirements change, you COULD lookup data.
The only reasons for changing your system to SQLite would be more comfort and maybe a more foolproof system. E.g. now you have to check if the file exists, parse the contents etc. and if you'd use SQLite, you don't have to verify the integrity of the data and Android also helps you a little. And you could use the data for other causes, like displaying them in a ListView.

Benefits of packaging sqlite db rather than creating?

When my app is first run, it creates 5 tables and inserts about 50 initial values. The user can delete any of these initial values if they want and they will add to them.
In this situation, what are the pros/cons between creating the db file and copying it over on first run and just putting a bunch of create/insert statements in onCreate?
It's crucial that user information doesn't get overwritten and because of that I'm leaning towards the create/insert statements, since those will fail/be minor if some bug triggers onCreate (if that's possible), whereas copying the db file would wipe the db.
There are no benefits of packaging the sqlite db rather than creating it IMO, just choose one and code accordingly, worrying that something it wrong with your code and deciding to use one method or another based on that is just an ice patch to bad programming.
No offense meant, I just think the reason why you are asking this question isnt right, the real difference would be between deciding something that just copies, but makes the APK bigger, but perhaps is faster than creating and populating.
I personally go with creating the DB from scratch, you will only do it "once", unless of course your update requires modifications to the DB or the user deleted the data. I would rather have the user wait a while, just once, and make the APK a considerable ammount of KBs lighter.
I think you've answered your own question as far as the cons of copying the whole db over. (Although I do like copying over databases for unit testing.) If you are looking for a less tedious way to populate those fifty values, you might try using .dump in sqlite3 and putting all of those insert statements into a single resource.
On the other hand, if onCreate gets called when it shouldn't, you probably have bigger problems to worry about.

Reasons for using readable SQLite database

The Android class SQLiteOpenHelper has a method to return a readable database as well as a read and writable database. Currently I am only using writable database and have no issues but I am wondering what the benefit would be to change to using readable only if I am only reading in an async task (or activity).
There might be performance benefits but I have not seen any reference to actual numbers. Also if I keep switching between readable and writable the change has an overhead that might take all the performance advantage away.
Does anybody have any real numbers or experience with this? Is it worth implementing separate access?
Good question. No numbers from me. The nearest explanation (from SQLLiteOpenHandler javadoc)
"This(getReadableDatabase) will be the same object returned by getWritableDatabase() unless some problem, such as a full disk, requires the database to be opened read-only. In that case, a read-only database object will be returned. If the problem is fixed, a future call to getWritableDatabase() may succeed, in which case the read-only database object will be closed and the read/write object will be returned in the future. "
I can't comment on performance benefits but I always try to work on the principle of 'good practice' (or 'best practice' even) for any access to any 'data' sources (text files, DBs or whatever).
Looking at things generically (not Android specific), the decisions to be made when deciding on access level, come down to the operation to be performed as well as any outside influences.
Two examples I can think of...
If an external process may have the
responsibility of maintaining data -
in this case it may have 'opened'
the data source in such a way that
it blocks all but 'read' access by
any other process during the maintenance phase. In this case,
your code will be denied access if
you request read/write access when
it isn't necessary.
The risk of compromising data integrity - hacks into systems from the outside world can be achieved via a security hole using internal code which has read/write access to data when it really only needed to have 'read' access.
OK, those points may or may not have relevance to Android (particularly if your data source is specific to your app) but, as I said, I try to look at things generically and use a 'best practice' approach. If I don't need 'write' access, I don't request it.

Categories

Resources