转载请注明出处。博客地址:http://blog.csdn.net/mylzc
java
介绍:数据库事务是由一组数据库操做序列组成,事务做为一个总体被执行。sql
事务的原子性:包含在其中的对数据库的操做序列最终要么所有执行,要么所有不执行。当所有执行时,事务对数据库的修改将生效;当所有不执行时,数据库维持原有的状态,不会被修改。数据库
问题:最近在作一个从sdcard导入数据到数据库的功能,当导入失败时,数据库要恢复到导入前的状态。使用数据库事务处理能很好地知足到咱们的需求。设计模式
咱们知道Android平台上使用的sqlite数据库是支持事务处理功能的,实现的代码以下:app
- SQLiteDatabase db =mOpenHelper.getWritableDatabase();
- db.beginTransaction();
-
- db.setTransactionSuccessful();
- db.endTransaction();
但是,对于已经封装成ContentProvider的Sqlite咱们应该如何让其支持事务处理功能呢?ide
解决办法:查看ContentProvider的API说明文档,咱们惊喜地发现 applyBatch(String authority,ArrayList<ContentProviderOperation> operations)这个方法,难道只须要直接使用这个方法就能够实现事务了?ui
谨慎起见咱们先来看看ContentProvider的源码,最后追踪到这个方法:this
- public ContentProviderResult[]applyBatch(ArrayList<ContentProviderOperation> operations)
- throwsOperationApplicationException {
- final int numOperations = operations.size();
- final ContentProviderResult[] results = newContentProviderResult[numOperations];
- for (int i = 0; i < numOperations; i++) {
- results[i] =operations.get(i).apply(this, results, i);
- }
- return results;
- }
从上面的代码中,咱们找不到和db.beginTransaction()、db.endTransaction()类似的方法,也就是说,这个方法只是进行简单的批处理,并无保障这些数据库操做的原子性。spa
好吧。咱们稍微动下脑筋,覆写ContentProvider的applyBatch()方法,为其添加事务处理功能。代码以下:.net
- @Override
- publicContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation>operations)
- throwsOperationApplicationException{
- SQLiteDatabasedb = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try{
- ContentProviderResult[]results = super.applyBatch(operations);
- db.setTransactionSuccessful();
- returnresults;
- }finally {
- db.endTransaction();
- }
- }
而后,咱们该如何使用这个applyBatch()方法呢?applyBatch()的第一个参数实现事务的Provider的authority 属性,第二个参数是数据库操做序列,构建数据库操做的对象使用了builder设计模式,下面是一个使用applyBatch()的例子:
- ArrayList<ContentProviderOperation>ops = new ArrayList<ContentProviderOperation>();
- ops.add(ContentProviderOperation.newDelete(Person.CONTENT_URI).build());
- ops.add(ContentProviderOperation.newInsert(Home.CONTENT_URI).withValues(values).build());
- getContentResolver().applyBatch(PROVIDER.AUTHORITY,ops);
总结:
一、sqlite支持事务处理操做
二、对于封装成ContentProvider的sqlite数据库,咱们能够经过覆写ContentProvider的applyBatch(Stringauthority, ArrayList<ContentProviderOperation> operations)方法来实现对事务处理的支持