Description: a database transaction is a sequence of database operations that are executed as a whole.
Atomicity of transactions: The sequence of database operations contained in the transaction is either executed in full or not executed in full. When all statements are executed, the transaction changes the database to take effect. When all statements are not executed, the database remains in the original State and will not be modified.
Problem: recently, I was working on a function to import data from sdcard to the database. When the Import fails, the database should be restored to the status before the import. The use of database service can well meet our needs.
We know that the sqlite database used on the Android platform supports the transaction processing function. The implementation code is as follows:
View plain
SQLiteDatabase db = mOpenHelper. getWritableDatabase ();
Db. beginTransaction (); // start the transaction
// Perform database operations such as insertdelete update
Db. setTransactionSuccessful (); // set the transaction tag to Successful
Db. endTransaction (); // submit the transaction
However, how should we enable Sqlite encapsulated as ContentProvider to support the transaction processing function?
Solution: Check the ContentProvider API instructions. We are pleasantly surprised to find applyBatch (String authority, ArrayList <ContentProviderOperation> operations, is it necessary to directly use this method to implement transactions?
To be cautious, let's take a look at the ContentProvider source code and finally track this method:
View plain
Public ContentProviderResult [] applyBatch (ArrayList <ContentProviderOperation> operations)
ThrowsOperationApplicationException {
Final int numOperations = operations. size ();
Final ContentProviderResult [] results = newContentProviderResult [numOperations];
For (int I = 0; I <numOperations; I ++) {// traverses the Database Operation Sequence
Results [I] = operations. get (I). apply (this, results, I); // execute database operations
}
Return results; // return results
}
From the code above, we cannot find and db. beginTransaction (), db. the endTransaction () method is similar. That is to say, this method only performs simple batch processing and does not guarantee the atomicity of these database operations.
Okay. We use our brains to overwrite the ContentProvider's applyBatch () method and add the transaction processing function to it. The Code is as follows:
View plain
@ Override
PublicContentProviderResult [] applyBatch (ArrayList <ContentProviderOperation> operations)
ThrowsOperationApplicationException {
SQLiteDatabasedb = mOpenHelper. getWritableDatabase ();
Db. beginTransaction (); // start the transaction
Try {
ContentProviderResult [] results = super. applyBatch (operations );
Db. setTransactionSuccessful (); // set the transaction tag to successful
Returnresults;
} Finally {
Db. endTransaction (); // end the transaction
}
}
Then, how can we use this applyBatch () method? The first parameter of applyBatch () implements the authority attribute of the Provider of the transaction, and the second parameter is the database operation sequence. The builder design mode is used to construct the database operation objects, the following is an example of using applyBatch:
View plain
ArrayList <ContentProviderOperation> ops = new ArrayList <ContentProviderOperation> ();
Ops. add (ContentProviderOperation. newDelete (Person. CONTENT_URI). build (); // add an operation to delete the Person table
Ops. add (ContentProviderOperation. newInsert (Home. CONTENT_URI). withValues (values). build (); // add a record to the Home table
GetContentResolver (). applyBatch (PROVIDER. AUTHORITY, ops); // process the transaction
Summary:
1. sqlite supports transaction processing
2. For the sqlite database encapsulated as ContentProvider, We can override the applyBatch (Stringauthority, ArrayList <ContentProviderOperation> operations) method of ContentProvider to support transaction processing.
Author's "lzc column"