0

I have a problem when I use a singleton database object inside class where I am getting database locked exception but when I use the same inside any method of the same class everything is fine, I am confused on the behavior. Below is the code: Database class: with singleton functionality

public class Database extends SQLiteOpenHelper{

        private static  String dbname="Director";
        private static int dbversion=1;
        SQLiteDatabase db;
        private Context m1Context;
        private static Database minstance;
        public Database(Context context) {

            super(context, dbname, null, dbversion);
            // TODO Auto-generated constructor stub

        }

        public synchronized static Database getInstance(Context m1Context){

            if (minstance==null){

            minstance=new Database(m1Context);
            }
            return minstance;


        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub

            STable st=new StockTable(m1Context);
            BTable bt=new BrokerageTable(m1Context);
            SList sl=new StockList(m1Context);

            db.execSQL(st.stocktable);
            db.execSQL(bt.Brokerage);
            db.execSQL(sl.Create());
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub

        }


    }

Now when I use the singleton instance in multiple classes I am getting error Database locked only when it is declared inside class but not inside method of same class. In below code line between astrik is one that is giving me error that is inside class and one between Plus sign is not giving error but I am doing same process in both cases.

public class SList {

    Context c1;
    Cursor getid;
    StockList(Context mContext){

        c1=mContext;
    }

    **//SQLiteDatabase sd=Database.getInstance(c1).getWritableDatabase();**
    String Ctable;
    //String ,selectIDgetstocks,deletestock;
    public String tablename="Stocklist";
    public String Column1="_id";
    public String Column2="Sname";
    ContentValues cv=new ContentValues();
    String getstocks="Select " + Column1 + " as _id, " + Column2 + " From "+ tablename;
    String selectID="Select Max("+  Column1 + ") from " + tablename;
    public String Create(){

        Ctable="Create Table " + tablename + " (" + Column1 + " INTEGER PRIMARY KEY , " + Column2 + " Text" + ")";

        return Ctable;
    }

    public void insert(int stockid,String name){

        cv.put(Column1, stockid);
        cv.put(Column2, name);
    ++Database.getInstance(c1).getWritableDatabase().insert(tablename,null,cv);++

    }


}

Can anyone please clear my confusion and also if possible let me know the functionality of the singleton usage. My idea is to use the sigleton instance in a database variable at the starting of the class and use that variable where ever needed in the whole class but that is not getting possible, No clue why but when I use the same instance at all the places then no error.

Please help me to understand.

Siva
  • 9,043
  • 12
  • 40
  • 63
  • Do you call db close if you finish using db? If you get instace call getWritableDatabse, another place call getWritableDatabse in same time, you can get error. instance which is getWratableDatabase, you call later, and close earlier. – Amadas Mar 24 '14 at 04:24
  • Thanks for your reply... I am not calling db.close but yes I have 5 activities and in all activities I need the getwritabledatabase instance... but in this case how I can achieve the functionality, Also where should I call db.close as if in one activity database usage completes another activity database usage starts. – Siva Mar 24 '14 at 04:29
  • Sorry, I don't understand your question clearly. Now, I understand. It's simple. You just using synchronized. This page's answer is help you. [link]http://stackoverflow.com/questions/574240/synchronized-block-vs-synchronized-method – Amadas Mar 24 '14 at 04:40
  • Singleton is different synchronized. Singleton pattern is just make one instance such as static(but it's some different). synchronized is safe instance which in many thread. it's do same function mutex or semaphore(but it's not same clearly.) – Amadas Mar 24 '14 at 04:44
  • Thanks for the link but why when I declare at the starting of the class it is giving me error and when I use it at statements it is not giving me database locked exception? Also can you please explain how and when to close the database object. – Siva Mar 24 '14 at 05:22

1 Answers1

0

If You use database, using this.

String query = "select * from table1";
synchronized(Database.getInstance(c1) )
        {
           db = Database.getInstance(c1).getWritableDatabase();
           Cursor c = db.rawQuery( query );
           c.moveToFirst();
           do
           {
                // do someting use database.
                Log.d( SList.class.getName(), c.getString( 0 ) );
           }while( c.moveToNext() );
           c.close();
           db.close();
        }
Amadas
  • 703
  • 1
  • 5
  • 10
  • thanks for your answer.. here I have one question `Database.getInstance(c1).getWritableDatabase();` this statement if I use multiple times for multiple queries (Like insert, select, delete) will there be any effect on database?. Also is it required to close database after every operation (insert, select or delete)..Thanks for your continous assistance – Siva Mar 24 '14 at 05:52
  • It's effect on database just data is changed(insert or delete). If you want many operation in time, just do and after close. If you use Cursor, close database when used finished use Cursor. And you can use transaction in android sqlite3. You want transaction, this link is help you. [link]http://stackoverflow.com/questions/8147440/android-database-transaction – Amadas Mar 24 '14 at 06:02
  • If you do this, it can be exception. First, insert data. Second, select and connect cursor using execSql. Third, delete data from database wehre is in cursor. After then, using cursor's data(getString, getInt or etc) when you get second time, it's can be exception. cursor isn't store data. just connect database's data. – Amadas Mar 24 '14 at 06:08
  • Sorry, I don't very well english, so my answer is difficult understand. But I try to explain what i know. – Amadas Mar 24 '14 at 06:11
  • No Problem @Amadas... you have certainly helped me... will accept the answer once I implement your suggestions in my code. – Siva Mar 24 '14 at 06:23
  • I guess @Siva never implemented the suggestions in their code :') – Denny Sep 25 '18 at 21:09