●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のアトミック性が保証されます。
以上です。