2017-07-27 57 views
0

我陷入了独特的境地。在我的应用程序中,我有本地数据库。不知何故,其中一张桌子上充斥着垃圾数据和数据库,规模庞大。当我知道的时候,尺寸超过了1GB。所以我不断收到数据库锁定异常,因为读取该表上的垃圾行非常缓慢。调试完成后,我想出了它是哪个表,现在我想删除它(删除整个表或删除所有行),但是每当我对该表执行任何操作时,数据库都会被锁定,并发生ANR。所以我不确定如何摆脱那张桌子。我无法卸载应用程序。删除大型sqlite表

请注意,我在我的android应用程序中使用GreenDao。

我试过以下的事情

1) DROP TABLE mytable; 
2) DELETE FROM mytable; 
3) DaoSession.getMyDao().deleteAll(); // this is a greedao method but it internally performs 2nd query I mentioned I think 

在所有的情况。它只是产生ANR.and应用程序数据库被锁定。

编辑:我在单独的线程也尝试过,它只是避免ANR但没有丢表和数据库仍然锁定。

锁定后我得到这个,每当其他线程试图写入数据库这是显而易见的。

E/SQLiteDatabase: Failed to open database '/data/user/0/myapp/databases/mydb.db'. 
android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: PRAGMA journal_mode 
################################################################# 
Error Code : 5 (SQLITE_BUSY) 
Caused By : The database file is locked. 
(database is locked (code 5): , while compiling: PRAGMA journal_mode) 
################################################################# 
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1000) 
at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:704) 
at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:385) 
at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:359) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:248) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:199) 
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:514) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178) 
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:934) 
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:895) 
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:708) 
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:646) 
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:283) 
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223) 
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187) 
at com.intouchapp.database.IntouchDb.getNewReadableDaoSesssion(IntouchDb.java:80) 
at com.intouchapp.models.ActivityLogsDb.getCursorOfAllResults(ActivityLogsDb.java:298) 
at com.intouchapp.services.ActivityLogsDbInsertionService.onHandleIntent(ActivityLogsDbInsertionService.java:73) 
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.os.HandlerThread.run(HandlerThread.java:61) 

而且我得到这个也

The connection pool for database '+data+user+0+myapp+databases+mydb' has been unable to grant a connection to thread 2262 (SyncAdapterThread-1) with flags 0x2 for 12.0060005 seconds. 
Connections: 1 active, 0 idle, 0 available. 

Requests in progress: 
executeForChangedRowCount started 12645ms ago - running, sql="DELETE FROM 'mytable'" 

这清楚地指出,这是不能够执行"DELETE FROM 'mytable'"这个特定的查询,因此锁。

+1

ANR发生在你在**主用户界面**线程中操作时间很长,操作时间很短,所以为了避免ANR,您必须在后台执行此操作 – pskink

+0

是的,我在单独的线程中尝试过。但它只是避免了ANR。删除表没有运气。 – Apr444

+0

那么栈跟踪是什么? – pskink

回答

0

当它用于写入操作时,SQLite锁定数据库。 您应该注意以下几点: -

  • DataBase操作应该在另一个不在UI线程中的线程中使用。
  • 数据库关闭所有的情况下完成任务
  • 后SQLiteOpenHelper类的一个实例
  • 总是使用endTransaction()方法
  • 关闭数据库的所有实例在finally块