我见过的Android SQLite交易的代码示例似乎会在db.setTransactionSuccessful()
之前自动调用db.endTransaction()
。
我想知道这是否是最佳做法,或者在致电db.setTransactionSuccessful()
之前是否应该进行一些有条件的检查。
在我的情况下,我正在覆盖ContentProvider
的{{1}}方法,如果我按照描述使用条件检查,我的方法将如下所示......
bulkInsert()
......这是正确的方法吗?
在 @Override
public int bulkInsert(Uri uri, ContentValues[] valuesArray) {
// Open a read / write database to support the transaction.
SQLiteDatabase db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case BRANDS_SEARCH:
int numInserts = 0;
db.beginTransaction();
for (int i = 0; i < valuesArray.length; i++) {
// Insert the values into the table
long rowId = db.insert(BRAND_NAMES_TABLE, null, valuesArray[i]);
if (rowId > -1) {
// Increment numInserts
numInserts++;
// Construct the URI of the newly inserted row.
Uri insertedId = ContentUris.withAppendedId(CONTENT_URI_BRANDS, rowId);
// Notify any observers of the change in the data set.
getContext().getContentResolver().notifyChange(insertedId, null);
}
}
boolean allInsertAttemptsWereSuccessful = (numInserts == valuesArray.length);
if (allInsertAttemptsWereSuccessful) {
db.setTransactionSuccessful(); //todo - should this be conditional?
}
else {
//todo - ???
}
db.endTransaction();
return numInserts;
default:
//break;
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
== allInsertAttemptsWereSuccessful
??
(我查看了Android docs,但提供的信息非常少。)
更新 - 新代码......
感谢laalto's answer,这是我的新(正确)代码......
false
答案 0 :(得分:12)
交易的规范模式:
beginTransaction();
try {
//db operations ...
setTransactionSuccessful();
} finally {
endTransaction();
}
这确保始终调用endTransaction()
(不留下悬空事务),并且在某些数据库操作中发生异常时回滚事务。如果您想出于自己的原因而中止交易,请不要致电setTransactionSuccessful()
或抛出异常。
答案 1 :(得分:1)
通常setTransactionSuccessful在endTransaction之前完成。
您也可以在为事务完成所有数据库操作后调用。但是,延迟endTransaction可能没有任何合理的理由。取决于你的逻辑。如果要确保在将chages提交到db之前应该成功执行某些java代码部分,则可以将setTransactionSuccessful和endTransaction furthur向下移动。
如果在startTransaction和endTransation之间写入的逻辑中有任何异常,那么它最终可能会打开事务和饥饿(从您的代码中可以清楚地看到dbHelper是成员变量。所以你将在所有的中使用相同的dbHelper内容提供商电话)。相同的dbHelper实例意味着相同的SqliteDatabase实例。
所以你必须添加try catch并最终结束事务。
答案 2 :(得分:1)
无需检查db.setTransactionSuccessful()
的条件。在insert语句之后我们可以编写db.setTransactionSuccessful()
语句。它将处理交易。
示例代码:
public void insertActivity(ActivityModel mModel){
db = getWritableDatabase();
ContentValues cv = new ContentValues();
try {
db.beginTransaction();
cv.put("id",mModel.getForm_id());
cv.put("_name",mModel.getForm_name());
cv.put("version_id",mModel.getLog_version_id());
db.insert("activity_type_status_mapping", null, cv);
db.setTransactionSuccessful();
} catch (Exception e){
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}