●blukInsert
ContentResolverやContentProviderClientにあるbulkInsertはアトミックな操作ではありません。トランザクションの開始なしに、連続してinsertするAPIです。
⇒ContentResolver.bulkInsert
・android.content.ContentProvider.bulkInsert(Uri, ContentValues[])
/**
* Override this to handle requests to insert a set of new rows, or the
* default implementation will iterate over the values and call
* {@link #insert} on each of them.
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
* after inserting.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
*
* @param uri The content:// URI of the insertion request.
* @param values An array of sets of column_name/value pairs to add to the database.
* @return The number of values that were inserted.
*/
public int bulkInsert(Uri uri, ContentValues[] values) {
int numValues = values.length;
for (int i = 0; i < numValues; i++) {
insert(uri, values[i]);
}
return numValues;
}
bulkInsertのアトミック性を保証したい場合、独自のプロバイダでbulkInsertをオーバーライドします。
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SQLiteDatabase db = MyDataBase.getInstance(getContext())
.getWritableDatabase();
db.beginTransaction();
try {
SQLiteStatement insertStmt = db
.compileStatement("INSERT INTO test "
+ "(name) VALUES (?);");
for (ContentValues value : values) {
insertStmt.bindString(1, value.getAsString("name"));
insertStmt.executeInsert();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
...
これでbulkInsertのアトミック性が保証されます。●applyBatch
blukInsertと同じく。ContentResolverやContentProviderClientにあるapplyBatchもアトミックな操作ではありません。
まとめてContentProviderOperationを実行するためのAPIで、トランザクションは開始されません。
⇒ContentResolver.applyBatch
・android.content.ContentProvider.applyBatch(ArrayList<ContentProviderOperation>)
/**
* Override this to handle requests to perform a batch of operations, or the
* default implementation will iterate over the operations and call
* {@link ContentProviderOperation#apply} on each of them.
* If all calls to {@link ContentProviderOperation#apply} succeed
* then a {@link ContentProviderResult} array with as many
* elements as there were operations will be returned. If any of the calls
* fail, it is up to the implementation how many of the others take effect.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
*
* @param operations the operations to apply
* @return the results of the applications
* @throws OperationApplicationException thrown if any operation fails.
* @see ContentProviderOperation#apply
*/
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
final int numOperations = operations.size();
final ContentProviderResult[] results = new ContentProviderResult[numOperations];
for (int i = 0; i < numOperations; i++) {
results[i] = operations.get(i).apply(this, results, i);
}
return results;
}
applyBatchのアトミック性を保証したい場合、独自のプロバイダでapplyBatchをオーバーライドします。
@Override
public ContentProviderResult[] applyBatch(
ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
SQLiteDatabase db = MyDataBase.getInstance(getContext())
.getWritableDatabase();
db.beginTransaction();
try {
ContentProviderResult[] result = super.applyBatch(operations);
db.setTransactionSuccessful();
return result;
} finally {
db.endTransaction();
}
}
これでapplyBatchのアトミック性が保証されます。以上です。