【问题标题】:sigleton instance for a database gives database locked exception in class but not in a method数据库的单例实例在类中给出数据库锁定异常,但在方法中没有
【发布时间】:2014-03-24 04:16:06
【问题描述】:

当我在类中使用单例数据库对象时遇到问题,我遇到了数据库锁定异常,但是当我在同一类的任何方法中使用相同时,一切都很好,我对行为感到困惑。下面是代码: 数据库类:具有单例功能

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

        }


    }

现在,当我在多个类中使用单例实例时,我收到错误数据库锁定仅当它在类内声明但不在同一类的方法内时。在下面的代码行中,astrik 之间的代码行给了我类内部的错误,而加号之间的代码行没有给出错误,但在这两种情况下我都在执行相同的过程。

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);++

    }


}

谁能解决我的困惑,如果可能的话,请告诉我单例用法的功能。我的想法是在类开始时在数据库变量中使用 sigleton 实例,并在整个类中需要的地方使用该变量,但这是不可能的,不知道为什么,但是当我在所有地方使用相同的实例时那么没有错误。

请帮我理解。

【问题讨论】:

  • 用完db后是否调用db close?如果你得到一个实例调用getWritableDatabse,另一个地方同时调用getWritableDatabse,你会得到错误。 getWratableDatabase 的实例,您稍后调用并提前关闭。
  • 感谢您的回复...我没有调用 db.close 但是是的,我有 5 个活动,在所有活动中我都需要 getwritabledatabase 实例...但在这种情况下,我如何实现该功能, 另外我应该在哪里调用 db.close 就好像在一个活动中数据库使用完成了另一个活动数据库使用开始。
  • 对不起,我不太清楚你的问题。现在我明白了。这很简单。你只是使用同步。这个页面的答案是帮助你。 [链接]stackoverflow.com/questions/574240/…
  • 单例同步不同。单例模式只是制作一个实例,例如静态(但它有些不同)。 synchronized 是许多线程中的安全实例。它的功能相同,互斥量或信号量(但不一样)
  • 感谢您的链接,但为什么当我在课程开始时声明它给我错误,而当我在语句中使用它时它没有给我数据库锁定异常?您能否解释一下如何以及何时关闭数据库对象。

标签: android singleton android-sqlite database-locking


【解决方案1】:

如果你使用数据库,使用这个。

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();
        }

【讨论】:

  • 感谢您的回答.. 这里我有一个问题Database.getInstance(c1).getWritableDatabase(); 这个语句如果我多次使用多个查询(如插入、选择、删除)会对数据库有任何影响吗?每次操作(插入、选择或删除)后是否需要关闭数据库。感谢您的持续帮助
  • 它对数据库的影响只是数据被更改(插入或删除)。如果您想及时进行许多操作,只需在关闭后执行。如果您使用 Cursor,请在使用完后关闭数据库使用 Cursor。您可以在 android sqlite3 中使用事务。你想要交易,这个链接对你有帮助。 [链接]stackoverflow.com/questions/8147440/…
  • 如果你这样做,它可能是例外。首先,插入数据。其次,使用 execSql 选择和连接游标。第三,从数据库中删除数据wehre在游标中。之后,当你第二次使用游标的数据(getString、getInt 等)时,它可能是异常的。游标不存储数据。只需连接数据库的数据。
  • 对不起,我的英语不太好,所以我的回答很难理解。但我试图解释我所知道的。
  • 没问题@Amadas ...您肯定帮助了我...一旦我在我的代码中实施您的建议,您将接受答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2016-01-30
相关资源
最近更新 更多