SQLite exception: Database is locked issue

android, exception, locking, sqlite

Solution

After doing some effort I did it (My app was working on perfect till android 2.3 but got db lock error when I used to run it on HoneyComb tablet). I did using Semaphores (using lock in critical sections).

Example 1

public class DbExp extends SQLiteOpenHelper{
    public static String Lock = "dblock";
    private static final String DATABASE_NAME = "db.db";
    private static final String TABLE_NAME = "table_name";

    public void delete(Context mContext){
        synchronized(Lock) {
            SQLiteDatabase db  = getWritableDatabase();
            db.delete(TABLE_NAME, null, null);
            db.close();
        }
    }

    public void insert(){
        synchronized(Lock) {
            SQLiteDatabase db  = getWritableDatabase();
            db.insert(TABLE_NAME, ..., ...);
            db.close();
        }
    }

}

Example 2

public class DB {
    public static String Lock = "dblock";
    private static final String DATABASE_NAME = "db.db";
    private static final String TABLE_NAME = "table_name";

    public void delete(Context mContext){
        synchronized(Lock) {
            SQLiteDatabase db  = mContext.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null);
            db.delete(TABLE_NAME, null, null);
            db.close();
        }
    }

    public void insert(Context mContext){
        synchronized(Lock) {
            SQLiteDatabase db  = mContext.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null);
            db.insert(TABLE_NAME, ..., ...);
            db.close();
        }
    }


}

Hope this would help Anyone in future :)

Problem

I'm having an issue with my SQLite database inside an Android app. It seems to happen every so often and I cannot reproduce it, but this is the report the Android Market gives. Basically I have first a splash screen activity that starts by checking if all the needed data is in the database. If not, it will install the data in a asynchronous thread and close the db connection. Then and only then can the main activity be started, which also opens and reads/writes the database. This code is executed from the onCreate method of the splash screen activity: ``` dbWord = new WordDBAdapter(this, myUI); dbWord.open(); if (dbWord.isDataInstalled()) { dbWord.close(); databaseInstalled = true; clickToStartView.setText(myUI.PRESS_TO_START); clickToStartView.startAnimation(myBlinkAnim); } else { // If not, try to install in asynchronous thread progressDialog = new ProgressDialog(this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage(myUI.INSTALLING_DB); progressDialog.setCancelable(false); new InstallDBData().execute(""); } ``` The code for the asynchronous thread is: ``` private class InstallDBData extends AsyncTask<String, Integer, Integer> { @Override protected Integer doInBackground(String... arg0) { progressDialog.setProgress(0); dbWord.installData(0, getApplicationContext()); progressDialog.setProgress(20); dbWord.installData(1, getApplicationContext()); progressDialog.setProgress(40); dbWord.installData(2, getApplicationContext()); progressDialog.setProgress(60); dbWord.installData(3, getApplicationContext()); progressDialog.setProgress(80); dbWord.installData(4, getApplicationContext()); progressDialog.setProgress(100); return 1; } protected void onPreExecute() { progressDialog.show(); } protected void onPostExecute(Integer x) { dbWord.close(); progressDialog.hide(); databaseInstalled = true; clickToStartView.setText(myUI.PRESS_TO_START); clickToStartView.startAnimation(myBlinkAnim); } } ``` These are important parts of the WordDBAdapter class, which is also used by the main activity: ``` public class WordDBAdapter { private DatabaseHelper mDbHelper; private SQLiteDatabase mDb; public WordDBAdapter open() throws android.database.SQLException { mDbHelper = new DatabaseHelper(mCtx); mDb = mDbHelper.getWritableDatabase(); return this; } public void close() { mDbHelper.close(); } ... } ``` I'm getting the following exceptions, which are similar but have a different message: First type of error message: ``` java.lang.RuntimeException: Unable to start activity ComponentInfo{example.flashcards.medical/com.example.flashcards.common.SplashWindow}: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE; at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1830) .... Caused by: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE; at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method) at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1870) at android.database.sqlite.SQLiteDatabase.beginTransactionWithListener(SQLiteDatabase.java:602) ``` Second type of error message: ``` java.lang.RuntimeException: Unable to start activity ComponentInfo{example.flashcards.medical/com.example.flashcards.common.SplashWindow}: android.database.sqlite.SQLiteException: database is locked at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784) .... Caused by: android.database.sqlite.SQLiteException: database is locked at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987) at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1855) at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820) at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854) ``` I would really like to not have to create a ContentProvider, because I believe its overkill if a simpler solution is available. Also, only this application has access to the database. Any suggestions on how this can be fixed?

Original source