Android SQLite:如果我的应用仅用于API> = 11,我应该对所有交易使用beginTransactionNonExclusive()而不是beginTransaction()吗?

时间:2015-03-24 02:31:08

标签: android sqlite transactions

在Android中执行交易时,从API 11开始有beginTransaction()beginTransactionNonExclusive()方法。

对于我来说,从文档中不太清楚我的应用程序是否仅针对API 11设备及以上设备,我应该使用beginTransactionNonExclusive()来处理我在我的应用程序中的所有事务。有没有缺点?

还提到,如果我理解正确,beginTransactionNonExclusive()正常工作,数据库必须启用预写日志记录。

我试图寻找一些关于此的文章,但我找不到谷歌的任何相关内容,我发现this article看起来很棒,但它是日文版。

非常感谢任何有关指导何时以及如何使用beginTransactionNonExclusive()的帮助。

2 个答案:

答案 0 :(得分:1)

我认为您应该将beginTransactionNonExclusiveenableWriteAheadLogging一起使用。

根据文件:

  

在数据库中启用预写日志记录是个好主意   将由多个线程同时访问和修改   同时。但是,预写日志记录使用的内存要多得多   比普通的日记,因为有多个连接   相同的数据库因此,如果数据库仅由单个线程使用,   或者如果优化并发性不是很重要,那么就预先写入   应禁用日志记录。]

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()

答案 1 :(得分:0)

beginTransactionNonExclusive 设置 TRANSACTION_MODE_IMMEDIATE transactionMode 标志,但 beginTransaction 设置 TRANSACTION_MODE_EXCLUSIVE transactionMode 标志。 由于SQLiteSession.java逻辑:

  // Set up the transaction such that we can back out safely
        // in case we fail partway.
        if (mTransactionStack == null) {
            // Execute SQL might throw a runtime exception.
            switch (transactionMode) {
                case TRANSACTION_MODE_IMMEDIATE:
                    mConnection.execute("BEGIN IMMEDIATE;", null,
                            cancellationSignal); // might throw
                    break;
                case TRANSACTION_MODE_EXCLUSIVE:
                    mConnection.execute("BEGIN EXCLUSIVE;", null,
                            cancellationSignal); // might throw
                    break;
                default:
                    mConnection.execute("BEGIN;", null, cancellationSignal); // might throw
                    break;
            }
        }

最终,立即独家出现了 SQLite 官方文档says

EXCLUSIVE与IMMEDIATE相似,因为立即开始写事务。 EXCLUSIVE和IMMEDIATE在WAL模式下是相同的,但是在其他日记模式下,EXCLUSIVE可以防止其他数据库连接在事务进行过程中读取数据库。

p.s:WAL是预写式日志记录

的缩写

另一方面,Android文档says

编写者应使用beginTransactionNonExclusive()或beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener)启动事务。非独占模式允许执行查询的其他线程可以读取数据库文件。

我知道您可能会感到困惑。您更信任谁,这是一个折衷方案! 我更喜欢Android文档,这意味着可以一起使用它们。

在数据库创建中使用:

db.enableWriteAheadLogging();

并用于交易:

db.beginTransactionNonExclusive();

p.s:不要记得 enableWriteAheadLogging 返回一个指定已启用的布尔值,因此在确定启用后使用 beginTransactionNonExclusive