0

I currently use the following pattern when accessing my SQLite database (possibly from different threads):

try(SQLiteDatabase db = new MySqliteOpenHelper(context).getWritableDatabase()) {
    ...
}

Until now I thought that it was clean and thread-safe, but I got some crashes due to "Database is locked".

Why is this pattern wrong and how should I change it?

sdabet
  • 18,360
  • 11
  • 89
  • 158

1 Answers1

1

MySqliteOpenHelper is not a singleton. To create a singleton in that class do the following in MySqliteOpenHelper.

1 Add a static instance variable of type MySqliteOpenHelper

2 Add a method called getInstance(Context) (body as shown below)

public synchronized static getInstance(Context context){
    if(instance == null){
        instance = new MySqliteOpenHelper(context);
    }
    return instance;
}

This is thread safe as you will always be using one object.

Ryan
  • 1,863
  • 13
  • 20
  • But I've read that `SQLiteOpenHelper` is supposed to handle thread safety, isn't it? – sdabet Jan 27 '17 at 17:00
  • I've never read anything similar, do you have a source? – Ryan Jan 27 '17 at 17:01
  • http://stackoverflow.com/a/6675272/569558 : "You shoud use locking-related SQLiteHelper methods to provide thread safety." – sdabet Jan 27 '17 at 17:01
  • That's saying `SQLiteDatabase` is thread safe not `SQLiteOpenHelper` – Ryan Jan 27 '17 at 17:02
  • You're right, but then why do I need to handle thread-safety myself if `SQLiteDatabase` handles it? – sdabet Jan 27 '17 at 17:03
  • You need to use `SQLiteOpenHelper` to open an instance `SQLiteDatabase`. Methods on `SQLiteDatabase` are thread safe by default. But to open the database you need to use `SQLiteOpenHelper ` which is not thread safe. – Ryan Jan 27 '17 at 17:06
  • At which level does the "database locked" issue happen? (SQLiteDatabase or SQLiteOpenHelper) – sdabet Jan 27 '17 at 17:08
  • It happens because you are creating *another* instance of `SQLiteOpenHelper` when one already exists (and has open handle to database). `SQLiteOpenHelper` then tries to open the database but fails because it is already in-use by the other `SQLiteOpenHelper` – Ryan Jan 27 '17 at 17:09
  • Last question then :) What establishes the db connection ? The instantation of `SQLiteOpenHelper` or the call to `getWritableDatabase()` ? – sdabet Jan 27 '17 at 17:10
  • `getWriteableDatabase` - https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase() – Ryan Jan 27 '17 at 17:11