I am trying to get a template that is not subject to multi-threaded access to my sqlite database. Besides what turns me on, I canβt reproduce the problem.
I have an application that uses a database, as well as Android and Android accounts to synchronize the data of my application. I assume that when they occur simultaneously, it falls. I get a lot of errors, such as:
* android.database.sqlite.SQLiteDatabaseLockedException: database is locked * android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5) * android.database.sqlite.SQLiteDatabaseLockedException: error code 5: database is locked * android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: PRAGMA journal_mode * android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 778) * android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/net.bicou.redmine/databases/redmine.db' to 'en_US'. \n Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)
Perhaps not all of them are associated with the same root cause, but I lost it.
I have:
DbAdapter abstract base class that extends with subclasses that want to manage a separate table- a class that manages an SQLite database called
DbManager that contains Lock
Users currently have a version of DbManager that is not a single. I plan to make DbManager singleton, so that all threads share the same object. This should not be a problem, because, as I understand / saw, background synchronization and the application have the same process.
Here are the classes (only relevant parts):
public abstract class DbAdapter { Context mContext; protected DbManager mDbManager; SQLiteDatabase mDb; public static final String KEY_ROWID = "_id"; public DbAdapter(final Context ctx) { mContext = ctx; } public DbAdapter(final DbAdapter other) { mContext = other.mContext; mDb = other.mDb; mDbManager = other.mDbManager;
The class that should process the database table extends the DbAdapter and implements methods such as select , insert , delete , etc.
Here's the database manager:
public class DbManager extends SQLiteOpenHelper { private static final String DB_FILE = "db"; private static final int DB_VERSION = 15; Context mContext; Lock mLock = new ReentrantLock();
OK, now questions.
- Is my lock set correctly? I'm really new to this, I don't know if
ReentrantLock good choice, and if I lock / unlock at the right time - Is my
synchronized method applied correctly? I mean, I put the synchronized around methods that I don't want to interrupt in parallel threads. It is right? Can you advise my synchronized use? - How can I reproduce the problem? I created a test that uses 3 threads that do simultaneous read / write access to the database and use some
Thread.sleep to ensure that the db open / close from each thread overlaps, but it does not crash. It really annoys me, I donβt think that there are many people who have a problem, so I donβt know how to reproduce. - Is my technical choice of
DbAdapter + DbManager good idea? Is there a better sample? - Can
DbManager make DbManager singleton?
android multithreading sqlite locking
Benoit duffez
source share