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

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

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

/**     * Begins a transaction in EXCLUSIVE mode.     * 

* Transactions can be nested. * When the outer transaction is ended all of * the work done in that transaction and all of the nested transactions will be committed or * rolled back. The changes will be rolled back if any transaction is ended without being * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. */ public void beginTransaction() { beginTransaction(null /* transactionStatusCallback */, true); }/** * Begins a transaction in IMMEDIATE mode. *Transactions can be nested. When * the outer transaction is ended all of the work done in that transaction * and all of the nested transactions will be committed or rolled back. The * changes will be rolled back if any transaction is ended without being * marked as clean (by calling setTransactionSuccessful). Otherwise they * will be committed. */ public void beginTransactionNonExclusive() { beginTransaction(null /* transactionStatusCallback */, false); }

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

private void beginTransaction(SQLiteTransactionListener transactionListener,            boolean exclusive) {        verifyDbIsOpen();        lockForced(BEGIN_SQL);        boolean ok = false;        try {           ...            // This thread didn't already have the lock, so begin a database            // transaction now.            if (exclusive && mConnectionPool == null) {                execSQL("BEGIN EXCLUSIVE;");            } else {                execSQL("BEGIN IMMEDIATE;");            }           ...        } finally {            if (!ok) {                // beginTransaction is called before the try block so we must release the lock in                // the case of failure.                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。

关于WAL模式会在另外一个blog讲解。

更多相关文章

  1. 【Android】入门案例(二)——JDBC连接MySql数据库实现登录
  2. Android通讯录数据库介绍与基本操作(增删改查)
  3. android 数据库同步
  4. Android 文件操作
  5. android 监听联系人数据库

随机推荐

  1. MySQL开发规范与使用技巧总结
  2. pycharm2017实现python3.6与mysql的连接
  3. MySQL执行状态的查看与分析
  4. Mysql覆盖索引详解
  5. MySQL主从同步延迟的原因及解决办法
  6. 详解数据库_MySQL: mysql函数
  7. linux下mysql乱码问题的解决方案
  8. 详解MySQL子查询(嵌套查询)、联结表、组合
  9. mysql索引基数概念与用法示例
  10. MySQL数据库中CAST与CONVERT函数实现类型