为ContentProvider添加数据库事务支持
2012-10-24 17:18
375 查看
介绍:数据库事务是由一组数据库操作序列组成,事务作为一个整体被执行。
事务的原子性:包含在其中的对数据库的操作序列最终要么全部执行,要么全部不执行。当全部执行时,事务对数据库的修改将生效;当全部不执行时,数据库维持原有的状态,不会被修改。
问题:最近在做一个从sdcard导入数据到数据库的功能,当导入失败时,数据库要恢复到导入前的状态。使用数据库事务处理能很好地满足到我们的需求。
我们知道Android平台上使用的sqlite数据库是支持事务处理功能的,实现的代码如下:
SQLiteDatabase db =mOpenHelper.getWritableDatabase();
db.beginTransaction(); //开始事务
... //进行insertdelete update等数据库操作
db.setTransactionSuccessful(); //设置事务标记为Successful
db.endTransaction(); //提交事务
可是,对于已经封装成ContentProvider的Sqlite我们应该如何让其支持事务处理功能呢?
解决办法:查看ContentProvider的API说明文档,我们惊喜地发现applyBatch(String
authority,ArrayList<ContentProviderOperation>
operations)这个方法,难道只需要直接使用这个方法就可以实现事务了?
谨慎起见我们先来看看ContentProvider的源码,最后追踪到这个方法:
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
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()相似的方法,也就是说,这个方法只是进行简单的批处理,并没有保障这些数据库操作的原子性。
好吧。我们稍微动下脑筋,覆写ContentProvider的applyBatch()方法,为其添加事务处理功能。代码如下:
@Override
publicContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation>operations)
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()的例子:
ArrayList<ContentProviderOperation>ops = new ArrayList<ContentProviderOperation>();
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<ContentProviderOperation>
operations)方法来实现对事务处理的支持.
事务的原子性:包含在其中的对数据库的操作序列最终要么全部执行,要么全部不执行。当全部执行时,事务对数据库的修改将生效;当全部不执行时,数据库维持原有的状态,不会被修改。
问题:最近在做一个从sdcard导入数据到数据库的功能,当导入失败时,数据库要恢复到导入前的状态。使用数据库事务处理能很好地满足到我们的需求。
我们知道Android平台上使用的sqlite数据库是支持事务处理功能的,实现的代码如下:
SQLiteDatabase db =mOpenHelper.getWritableDatabase();
db.beginTransaction(); //开始事务
... //进行insertdelete update等数据库操作
db.setTransactionSuccessful(); //设置事务标记为Successful
db.endTransaction(); //提交事务
可是,对于已经封装成ContentProvider的Sqlite我们应该如何让其支持事务处理功能呢?
解决办法:查看ContentProvider的API说明文档,我们惊喜地发现applyBatch(String
authority,ArrayList<ContentProviderOperation>
operations)这个方法,难道只需要直接使用这个方法就可以实现事务了?
谨慎起见我们先来看看ContentProvider的源码,最后追踪到这个方法:
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
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()相似的方法,也就是说,这个方法只是进行简单的批处理,并没有保障这些数据库操作的原子性。
好吧。我们稍微动下脑筋,覆写ContentProvider的applyBatch()方法,为其添加事务处理功能。代码如下:
@Override
publicContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation>operations)
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()的例子:
ArrayList<ContentProviderOperation>ops = new ArrayList<ContentProviderOperation>();
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<ContentProviderOperation>
operations)方法来实现对事务处理的支持.
相关文章推荐
- 为ContentProvider添加数据库事务支持
- 为ContentProvider添加数据库事务支持
- Android小技巧(二):为ContentProvider添加数据库事务支持
- Android小技巧(二):为ContentProvider添加数据库事务支持
- 为ContentProvider添加数据库事务支持
- 基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持
- c#批量插入数据到数据库【支持事务操作】
- ThinkPHP数据库的事务支持
- ASP中对数据库表的操作,可使用事务处理,并支持多事务处理
- 给JFinal添加 Sqlite 数据库支持
- [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction
- ThinkPHP5-数据库操作和事务支持
- 此数据库没有有效所有者,因此无法安装数据库关系图支持对象。若要继续,请首先使用“数据库属性”对话框的“文件”页或ALTER AUTHORIZATION语句将数据库所有者设置为有效登录名,然后再添加数据库关系图支持对象
- 系出名门Android(9) - 数据库支持(SQLite), 内容提供器(ContentProvider)
- 备份数据库用到的相关代码(在数据库事务中添加)
- 动态添加数据源,根据用户登录切换数据库.编程式Spring事务.
- 实现ContentProvider事务操作以及对数据库的监控
- 在Eclipse中添加数据库支持
- 系出名门Android(9) - 数据库支持(SQLite), 内容提供器(ContentProvider)
- 在已有的postgreSQL中数据库添加postgis支持