So I'm having some problems with my connection to SQLite, where I'm not finding a workaround.
Scenery
My scenario is as follows:
- I synchronize the data of my application with a legacy system through a WebService;
- Synchronization is done through a Thread that checks what is new in the legacy database and initiates several other Threads to retrieve the data and saves it to its local base (SQLite);
- For each entity that finds new data in the legacy database, a new Thread is opened, (each entity has an EndPoint, where it is accessed, downloaded, saved, and then terminated by Thread). If there are new clients in the legacy base, a request is initiated that will fetch all new clients, and save them to my SQLite client table, this would run on a Thread;
Problem
The problem is that even though I use AsyncTask.SERIAL_EXECUTOR
which only runs one Thread at a time, between one opening and another connection it ends up generating Lock problem, where I can not get the current connection reference and when trying to create a new one it accuses that the db is Locked .
I believe that my problem is neither with the threads running concurrently, but in my% 2 of connection management, which I am currently using is:
public abstract class GConexaoAdapter {
private final DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
protected final Context ctx;
public GConexaoAdapter(Context ctx, String dbName, int dbVersion) {
this.mDbHelper = new DatabaseHelper(ctx, dbName, dbVersion);
this.ctx = ctx;
}
private void open() {
try {
synchronized (ctx) {
synchronized (mDbHelper) {
if (mDb == null) {
mDb = mDbHelper.getWritableDatabase();
} else {
synchronized (mDb) {
mDb = mDbHelper.getWritableDatabase();
}
}
}
}
} catch (IllegalStateException e) {
e.printStackTrace();
if (mDb == null || !mDb.isOpen())
mDb = ctx.openOrCreateDatabase(mDbHelper.getDatabaseName(), 0,
null);
Log.i("TRATAR", "tratar");
}
}
protected SQLiteDatabase getConexao() {
synchronized (ctx) {
synchronized (mDbHelper) {
if (mDb == null) {
this.open();
} else if (!mDb.isOpen()) {
synchronized (mDb) {
if (!mDb.isOpen()) {
this.open();
}
}
}
return mDb;
}
}
}
protected void closeConexao() {
synchronized (ctx) {
synchronized (mDbHelper) {
if (mDb != null && mDb.isOpen()) {
synchronized (mDb) {
if (mDb.isOpen()) {
if (mDb.inTransaction()) {
mDb.endTransaction();
}
mDb.close();
}
}
}
}
}
}
private static class DatabaseHelper extends SQLiteOpenHelper {
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
if (!db.isReadOnly()) {
// db.execSQL("PRAGMA foreign_keys=ON;");
}
}
DatabaseHelper(Context context, String dbNome, int dbVersion) {
super(context, dbNome, null, dbVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
I think I do not even need all the class
I have, I tried several solutions that I found and none of them brought me the expected result.
Question?
I believe there's even a Cake recipe for this type of connection management. Because I should not be the only one in need of a solution as it is.
So how would you manage to efficiently manage my connection to the SQLite database?
Very important remark:
I would like to manage the SQLite connection between multiple concurrent threads, but without causing locks that end up generating exceptions and violating data integrity !