介绍:数据库事务是由一组数据库操作序列组成,事务作为一个整体被执行。
事务的原子性:包含在其中的对数据库的操作序列最终要么全部执行,要么全部不执行。当全部执行时,事务对数据库的修改将生效;当全部不执行时,数据库维持原有的状态,不会被修改。
问题:最近在做一个从sdcard导入数据到数据库的功能,当导入失败时,数据库要恢复到导入前的状态。使用数据库事务处理能很好地满足到我们的需求。
我们知道Android平台上使用的sqlite数据库是支持事务处理功能的,实现的代码如下:
view plain
SQLiteDatabase db =mOpenHelper.getWritableDatabase();
                   db.beginTransaction();//开始事务
//进行insertdelete update等数据库操作
db.setTransactionSuccessful();//设置事务标记为Successful
db.endTransaction();//提交事务
可是,对于已经封装成ContentProvider的Sqlite我们应该如何让其支持事务处理功能呢?
解决办法:查看ContentProvider的API说明文档,我们惊喜地发现applyBatch(String authority,ArrayList operations)这个方法,难道只需要直接使用这个方法就可以实现事务了?
谨慎起见我们先来看看ContentProvider的源码,最后追踪到这个方法:
view plain
public ContentProviderResult[]applyBatch(ArrayList operations)
            throwsOperationApplicationException {
       final int numOperations = operations.size();
       final ContentProviderResult[] results = newContentProviderResult[numOperations];
       for (int i = 0; i < numOperations; i++) {//遍历数据库操作序列
            results =operations.get(i).apply(this, results, i);//执行数据库操作
       }
       return results;//返回结果
   }

从上面的代码中,我们找不到和db.beginTransaction()、db.endTransaction()相似的方法,也就是说,这个方法只是进行简单的批处理,并没有保障这些数据库操作的原子性。
好吧。我们稍微动下脑筋,覆写ContentProvider的applyBatch()方法,为其添加事务处理功能。代码如下:
view plain
@Override
publicContentProviderResult[] applyBatch(ArrayListoperations)
            throwsOperationApplicationException{
          SQLiteDatabasedb = mOpenHelper.getWritableDatabase();
          db.beginTransaction();//开始事务
          try{
                   ContentProviderResult[]results = super.applyBatch(operations);
                   db.setTransactionSuccessful();//设置事务标记为successful
                   returnresults;
          }finally {
                   db.endTransaction();//结束事务
          }
}

然后,我们该如何使用这个applyBatch()方法呢?applyBatch()的第一个参数实现事务的Provider的authority属性,第二个参数是数据库操作序列,构建数据库操作的对象使用了builder设计模式,下面是一个使用applyBatch()的例子:
view plain
ArrayListops = new ArrayList();
ops.add(ContentProviderOperation.newDelete(Person.CONTENT_URI).build());//添加一个删除Person表的操作
ops.add(ContentProviderOperation.newInsert(Home.CONTENT_URI).withValues(values).build());//添加一条记录到Home表
getContentResolver().applyBatch(PROVIDER.AUTHORITY,ops);//处理事务
总结:
1、sqlite支持事务处理操作
2、对于封装成ContentProvider的sqlite数据库,我们可以通过覆写ContentProvider的applyBatch(Stringauthority, ArrayList operations)方法来实现对事务处理的支持

更多相关文章

  1. SnappyDB—Android上的NoSQL数据库
  2. Android(安卓)对用户名密码进行加密操作存储在本地
  3. Android的轻量级数据库sqlite、以及文件存取byte数组
  4. Android中数据库常见操作实例分析
  5. UI效果(9): 屏幕相关操作
  6. Android(安卓)UI Design Tips(Google官方出品:Android(安卓)UI 设
  7. Android(安卓)中的文件操作
  8. Android(安卓)UI秘笈:谨记该做什么不该做什么
  9. ANDROID+SQLITE详解2

随机推荐

  1. Context和SQLiteOpenHelper创建数据库
  2. android 显示16色的图片:输入用颜色矩阵,显
  3. Android(安卓)Animation 高手必读 之一 T
  4. No content provider found for permissi
  5. Android(安卓)操纵File查看文件大小,清理
  6. Android使用Handler实现下载文件功能
  7. Android(安卓)通知流程
  8. Android(安卓)4游戏编程入门经典
  9. DrawerLayout使用详解
  10. android使用groovy环境配置及所遇问题