Android SQLite 事务和多线程

标签 android multithreading sqlite transactions android-sqlite

在我的应用程序中,我调用一些网络服务来更新数据库。 每个 Web 服务调用都在特定线程中进行,导致多个线程“一次”更新数据库对象。

在每个线程中,我都使用这样的事务:

Thread 1 (webservice 1)
beginTransaction()
insert a row in the table 1
update a row in the table 1
endTransaction()

Thread 2 (webservice 2)
beginTransaction()
update a row in the table 2
update a row in the table 2
endTransaction()

但是我在谷歌搜索后无法回答一个问题; 由于事务在不同的线程中处理,它们是否彼此不同?换句话说,数据库使用不同的“语句堆栈”还是通用的?

根据我的阅读,我了解到事务在同一个堆栈中,即在线程 1 中提交事务可能会在表 2 上提交更新。 例如,我认为可能发生的 DB 语句堆栈:

beginTransaction() //Thread 1 begins a transaction
insert a row in the table 1
update a row in the table 1
beginTransaction() //Thread 2 begins a transaction
update a row in the table 2
update a row in the table 2
endTransaction() //Thread 2 ends a transaction
endTransaction() //Thread 1 ends a transaction

如果是真的,我怎样才能使我的交易真正具有排他性?我是否必须 BEGIN EXCLUSIVE TRANSACTION 并在所有地方处理 SQLITE_BUSY 错误,还是有更简单的方法?

最佳答案

我鼓励进一步阅读以了解事务模式的工作原理。来自 SQLite 用户指南:

Transactions can be deferred, immediate, or exclusive. The default transaction behavior is deferred. Deferred means that no locks are acquired on the database until the database is first accessed. Thus with a deferred transaction, the BEGIN statement itself does nothing to the filesystem. Locks are not acquired until the first read or write operation. The first read operation against a database creates a SHARED lock and the first write operation creates a RESERVED lock. Because the acquisition of locks is deferred until they are needed, it is possible that another thread or process could create a separate transaction and write to the database after the BEGIN on the current thread has executed. If the transaction is immediate, then RESERVED locks are acquired on all databases as soon as the BEGIN command is executed, without waiting for the database to be used. After a BEGIN IMMEDIATE, no other database connection will be able to write to the database or do a BEGIN IMMEDIATE or BEGIN EXCLUSIVE. Other processes can continue to read from the database, however. An exclusive transaction causes EXCLUSIVE locks to be acquired on all databases. After a BEGIN EXCLUSIVE, no other database connection except for read_uncommitted connections will be able to read the database and no other connection without exception will be able to write the database until the transaction is complete.

https://www.sqlite.org/lang_transaction.html

Android API 提供了一种处理这些事务模式的方法,因此请选择更适合您的应用程序的方法。

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

关于Android SQLite 事务和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28717843/

相关文章:

java - 如何在 libgdx 上使用 SQLite(仅限核心和项目)?

ios - Swift SQLite SQL 计数

ios - 基于SQLite的核心数据: Drop indexes to reduce size and recreate them later

android - 如何禁用图库中的滚动

Android 键盘与 EditText 重叠

Android AAR 库 - bundle node_modules

C++ TCP 服务器-客户端小问题

c# - 新线程签名(静态与非静态方法)

android - 搜索 ListView 标志的功能 - 无法解析方法“getFilter()”

java - Java 中最佳队列消费者实现