Android事务IMMEDIATE与EXCLUSIVE模式

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

创新互联建站拥有十多年成都网站建设工作经验,为各大企业提供网站制作、成都做网站服务,对于网页设计、PC网站建设(电脑版网站建设)、重庆App定制开发、wap网站建设(手机版网站建设)、程序开发、网站优化(SEO优化)、微网站、域名注册等,凭借多年来在互联网的打拼,我们在互联网网站建设行业积累了很多网站制作、网站设计、网络营销经验,集策划、开发、设计、营销、管理等网站化运作于一体,具备承接各种规模类型的网站建设项目的能力。

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。


标题名称:Android事务IMMEDIATE与EXCLUSIVE模式
URL网址:http://ybzwz.com/article/jsdjpc.html