ban*_*ing 11 sqlite android transactions
我见过的Android SQLite事务的代码示例似乎在db.setTransactionSuccessful()之前自动调用db.endTransaction().
我想知道这是否是最佳做法,或者是否应该在打电话之前进行一些有条件的检查db.setTransactionSuccessful().
在我的情况下,我重写ContentProvider的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);
}
}
Run Code Online (Sandbox Code Playgroud)
......这是正确的方法吗?
在allInsertAttemptsWereSuccessful== false?? 的情况下我应该采取什么行动?
(我查看了Android文档,但提供的信息非常少.)
更新 - 新代码......
感谢laalto的回答,这是我的新(正确)代码......
/**
* Attempts a bulk insert. Outcome will either be all inserts succeeded
* or all inserts failed.
*/
@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:
/*
* Begin the transaction
*/
db.beginTransaction();
try {
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) {
/*
* 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);
}
else {
/*
* Give up (as we need all insert attempts to succeed)
*/
throw new Exception("Could not insert row");
}
}
/*
* All insert attempts succeeded
*/
db.setTransactionSuccessful();
return valuesArray.length;
}
catch(Exception e) {
/*
* If any insert attempt failed, then setTransactionSuccessful() will not be called so no rows will actually be inserted
*/
return 0;
}
finally {
/*
* Always end the transaction
*/
db.endTransaction();
}
default:
//break;
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
Run Code Online (Sandbox Code Playgroud)
laa*_*lto 13
交易的规范模式:
beginTransaction();
try {
//db operations ...
setTransactionSuccessful();
} finally {
endTransaction();
}
Run Code Online (Sandbox Code Playgroud)
这可确保endTransaction()始终调用(不会留下悬空事务),并在某些数据库操作中发生异常时回滚事务.如果您想出于自己的原因中止事务,只需不要调用setTransactionSuccessful()或抛出异常.