【问题标题】:Android database was locked after importing multiple csv files导入多个 csv 文件后,Android 数据库被锁定
【发布时间】:2014-07-11 15:18:03
【问题描述】:

我正在尝试使用 for 循环将多个 csv 文件导入 Android sqlite。 但是,当应用程序尝试将 csv 内容导入数据库时​​,数据库将被锁定,并且与数据库相关的所有其他功能都会失败。

这是我的代码 导入函数:

Button button_import_csv = (Button) findViewById(R.id.button_import);
    button_import_csv.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){

            DatabaseHelper helper = new DatabaseHelper(getApplicationContext());
            SQLiteDatabase db = helper.getWritableDatabase();
            int returnvalue;
            long ret;
            Log.d("ice","database opened");
            returnvalue=db.delete(tableName[0], null, null );
            Log.d("ice","Returnvalue of deleting table0:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[1], null, null );
            Log.d("ice","Returnvalue of deleting table1:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[2], null, null );
            Log.d("ice","Returnvalue of deleting table2:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[3], null, null );
            Log.d("ice","Returnvalue of deleting table3:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[4], null, null );
            Log.d("ice","Returnvalue of deleting table4:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[5], null, null );
            Log.d("ice","Returnvalue of deleting table5:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[6], null, null );
            Log.d("ice","Returnvalue of deleting table6:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[7], null, null );
            Log.d("ice","Returnvalue of deleting table7:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[8], null, null );
            Log.d("ice","Returnvalue of deleting table8:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[9], null, null );
            Log.d("ice","Returnvalue of deleting table9:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[10], null, null );
            Log.d("ice","Returnvalue of deleting table10:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[11], null, null );
            Log.d("ice","Returnvalue of deleting table11:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[12], null, null );
            Log.d("ice","Returnvalue of deleting table12:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[13], null, null );
            Log.d("ice","Returnvalue of deleting table13:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[14], null, null );
            Log.d("ice","Returnvalue of deleting table14:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[15], null, null );
            Log.d("ice","Returnvalue of deleting table15:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[16], null, null );
            Log.d("ice","Returnvalue of deleting table16:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[17], null, null );
            Log.d("ice","Returnvalue of deleting table17:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[18], null, null );
            Log.d("ice","Returnvalue of deleting table18:" + Integer.toString(returnvalue));
            returnvalue=db.delete(tableName[19], null, null );
            Log.d("ice","Returnvalue of deleting table19:" + Integer.toString(returnvalue));

            Log.d("ice","old data existed in database was all cleared");
            try{
                File csvpath = new File("/sdcard/downloadedfolder/"+route_folder);
                Log.d("ice","Path of csv folder get in modile");
                File[] csvfile = csvpath.listFiles();
                //get all csv files' name and store it as array
                Log.d("ice","Name of csv was get and change into string");
                //Put all name of csv into a string array
                /*FileReader file = new FileReader("/sdcard/downloadedfolder/A1/adv_sales_order.csv");
                BufferedReader buffer = new BufferedReader(file);*/
                for(int j=0;j<20;j++){
                    FileReader file = new FileReader(csvfile[j]);
                    Log.d("ice","Current file reading");
                    Log.d("ice","csvfile"+Integer.toString(j)+": "+file.toString());
                    BufferedReader buffer = new BufferedReader(file);
                    ContentValues contentValues=new ContentValues();
                    String line = buffer.readLine();            //read first line to get the column
                    Log.d("ice","Column of "+file.toString()+": "+ line);
                    String[] cols = line.split("\t");           
                    db.beginTransaction();

                    while ((line = buffer.readLine()) != null) {
                        Log.d("ice","Read next record");
                        Log.d("ice","Line"+ Integer.toString(j)+": "+ line);
                        //read every single line of record in csv
                        String[] str = line.split("\t");
                        for (int i = 0; i < cols.length; i++) {
                            contentValues.put(cols[i], str[i]);
                            Log.d("ice",cols[i] + "= " + str[i]);
                        }
                        ret = db.insert(tableName[j], null, contentValues);
                        Log.d("ice","Import result for " + tableName[j] +"= ");
                        Log.d("ice", Long.toString(ret));

                    }
                    buffer.close();
                }

                db.setTransactionSuccessful();
                db.endTransaction();
            }catch (IOException e){

            }

            helper.close();
        }
    });

这是任何调用数据库的函数时的错误日志:

07-11 10:39:52.076:E/SQLiteDatabase(25198):无法打开数据库“/data/data/com.iceapp/databases/icedb.db”。 07-11 10:39:52.076: E/SQLiteDatabase(25198): android.database.sqlite.SQLiteDatabaseLockedException: 数据库被锁定 (代码 5): , 编译时: PRAGMA journal_mode

我也在logcat中找到了相关消息

/data/data/com.iceapp/databases/icedb.db 的连接池已关闭,但仍有 1 个连接在使用。当它们被释放回池中时,它们将被关闭。

我不知道为什么关闭数据库以及正在使用哪个连接。谁能给我一些帮助?谢谢。

【问题讨论】:

  • 试着把这两行,db.setTransactionSuccessful(); db.endTransaction();在finally块中的forloop内部并检查
  • @madhu 抱歉,我可以将 finally 块放入 for 循环中。它给出了一个语法错误。
  • 我通过将所有与 Transaction 相关的代码作为注释来解决 about 问题。我不知道为什么那些代码会锁定数据库。

标签: android database sqlite


【解决方案1】:
  1. 确保您的 SQLiteOpenHelper 是 Singleton,这将防止数据库被锁定。

  2. 始终调用 db.yieldIfContendedSafely()。做交易的时候。这将防止数据库死锁。

    db.beginTransaction();

    对于 (..) {

    ...//insert
    
     db.yieldIfContendedSafely();
    

    }

    db.setTransactionSuccessful();

    db.endTransaction();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 2019-02-05
    相关资源
    最近更新 更多