我有一个insert语句,我的应用需要大约25秒来插入~1000行。我正在尝试使用Transactions
来加快处理时间,但是我无法实现它。
以下是我inserting
中DatabaseHandler
的方法:
public boolean insertQuestions(String gid, String qid, String qname) {
SQLiteDatabase db = this.getWritableDatabase();
db.beginTransaction();
try {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_GID, gid);
contentValues.put(KEY_QID, qid);
contentValues.put(KEY_QNAME, qname);
long result = db.insert(TABLE_QUESTIONS, null, contentValues);
db.setTransactionSuccessful();
if (result == -1) {
db.close();
return false;
} else {
db.close();
return true;
}
} finally {
db.endTransaction(); //Error is here
}
}
当我尝试运行上述方法时,我收到以下错误:
08-28 15:50:40.961 20539-20539/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.murrion.navigationdrawer, PID: 20539
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /storage/emulated/0/testapp3.db
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
at com.murrion.navigationdrawer.utils.DatabaseHandler.insertQuestions(DatabaseHandler.java:197)
该语句正在我的Activity中的Asynctask方法中运行。
答案 0 :(得分:4)
您已经在结束交易前关闭了数据库,而是在结束后关闭它。
public boolean insertQuestions(String gid, String qid, String qname) {
SQLiteDatabase db = this.getWritableDatabase();
boolean wasSuccess = true;
try {
db.beginTransaction();
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_GID, gid);
contentValues.put(KEY_QID, qid);
contentValues.put(KEY_QNAME, qname);
long result = db.insert(TABLE_QUESTIONS, null, contentValues);
if (result == -1) {
wasSuccess = false;
} else {
db.setTransactionSuccessful();
}
} finally {
db.endTransaction();
db.close();
}
return wasSuccess;
}
答案 1 :(得分:3)
两个问题
您可以创建一个Question
类来封装单个问题的数据。在这种情况下,您的方法可能如下所示:
public boolean insertQuestions(List<Question> questions) {
SQLiteDatabase db = this.getWritableDatabase();
db.beginTransaction();
try {
ContentValues contentValues = new ContentValues();
for (Question question : Questions) {
contentValues.put(KEY_GID, question.gid);
contentValues.put(KEY_QID, question.qid);
contentValues.put(KEY_QNAME, question.qname);
db.insert(TABLE_QUESTIONS, null, contentValues);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
答案 2 :(得分:1)
我认为您正在逐个使用beginTransaction()
插入问题。因此endTransaction()
和db.beginTransaction();
for (entry : listOfQuestions) {
db.insertQuestions("","","");
}
db.setTransactionSuccessful();
db.endTransaction();
多次调用效率低下。
加速交易需要进行一些更改:
您必须先将所有问题都插入数组,然后使用:
public boolean insertQuestions(String gid, String qid, String qname) {
SQLiteDatabase db = this.getWritableDatabase();
boolean wasSuccess = true;
try {
db.beginTransaction();
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_GID, gid);
contentValues.put(KEY_QID, qid);
contentValues.put(KEY_QNAME, qname);
long result = db.insert(TABLE_QUESTIONS, null, contentValues);
if (result == -1) {
wasSuccess = false;
} else {
db.setTransactionSuccessful();
}
} finally {
db.endTransaction();
db.close();
}
return wasSuccess;
}
您方法中的一些修改。
{{1}}
我希望它有所帮助!