事务是数据库保证数据唯一性和一致性的技术,对于数据库一个或一组写操作要保证是一个原子操作就需要使用事务,android使用事务的常见形式如下:


SQLiteDatabasedb=null;...db.beginTransaction();try{db.setTransactionSuccessful();...}finally{db.endTransaction();}


那么db.beginTransaction是一个什么操作? 我们来看下SQLiteDatabase的源码:



/***BeginsatransactioninEXCLUSIVEmode.*<p>*Transactionscanbenested.*Whentheoutertransactionisendedallof*theworkdoneinthattransactionandallofthenestedtransactionswillbecommittedor*rolledback.Thechangeswillberolledbackifanytransactionisendedwithoutbeing*markedasclean(bycallingsetTransactionSuccessful).Otherwisetheywillbecommitted.*/publicvoidbeginTransaction(){beginTransaction(null/*transactionStatusCallback*/,true);}/***BeginsatransactioninIMMEDIATEmode.*Transactionscanbenested.When*theoutertransactionisendedalloftheworkdoneinthattransaction*andallofthenestedtransactionswillbecommittedorrolledback.The*changeswillberolledbackifanytransactionisendedwithoutbeing*markedasclean(bycallingsetTransactionSuccessful).Otherwisethey*willbecommitted.*/publicvoidbeginTransactionNonExclusive(){beginTransaction(null/*transactionStatusCallback*/,false);}

从注释中可以看到beginTransaction的调用使用EXCLUSIVE mode, beginTransactionNonExclusive使用IMMEDIATE mode,以上两个方法都是调用SQLiteDatabase的私有方法beginTransaction,两个方法不同之处在于第二个实参true|false, 这个私有方法源码:


privatevoidbeginTransaction(SQLiteTransactionListenertransactionListener,booleanexclusive){verifyDbIsOpen();lockForced(BEGIN_SQL);booleanok=false;try{...//Thisthreaddidn'talreadyhavethelock,sobeginadatabase//transactionnow.if(exclusive&&mConnectionPool==null){execSQL("BEGINEXCLUSIVE;");}else{execSQL("BEGINIMMEDIATE;");}...}finally{if(!ok){//beginTransactioniscalledbeforethetryblocksowemustreleasethelockin//thecaseoffailure.unlockForced();}}}

当形参exclusive为true并且mConnectionPool==null是执行:execSQL("BEGIN EXCLUSIVE;"); false执行execSQL("BEGIN IMMEDIATE;");


BEGIN EXCLUSIVE:当前事务在没有结束之前任何android中的其他线程或进程都无法对数据库进行读写操作。
BEGIN IMMEDIATE:确保android中其他线程或者进程之间读取数据不能修改数据库。

为什么需要判断mConnectionPool==null这个条件,如果当mConnectionPool!=null 表示调用了enableWriteAheadLogging,也就是使用了WAL MODE。 使用WAL模式是能够提高并发性,读与写互不阻塞,而执行BEGIN EXCLUSIVE却降低了并发,互相矛盾,所以当以上两个条件都成立的情况下执行BEGIN EXCLUSIVE。


更多相关文章

  1. Android端JQueryMobile使用教程(二)
  2. Android(安卓)C编程技巧
  3. Android系列教程之六:TextView小组件的使用--附带超链接和跑马灯
  4. Android(安卓)菜单(Menu)控件的使用
  5. Android之使用传感器获取相应数据
  6. android5中数据存储方式详解
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. 用Excel做相关性分析
  2. 世界是自己的。人来人往,车水马龙。我只是
  3. 从零到一学懂区块链(4):密钥
  4. 用Excel做直方图(1):随机数发生器
  5. 路遥作品读后感
  6. 从零到一学懂区块链(5):工作量证明
  7. 描述性统计分析
  8. 《请活着,不要装活着》
  9. Android中的Frame动画
  10. 用Excel做回归分析