在我的应用程序中,我调用了一些webservices来更新数据库。 每个webservice调用都在一个特定的线程中进行,导致多个线程一次更新数据库对象"。
在每个帖子中,我都使用这样的交易:
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
错误或是否有更容易的事情?
答案 0 :(得分:1)
我鼓励进一步阅读以了解交易模式的工作原理。来自SQLite用户指南:
交易可以是延期,即时或独家。默认事务行为是延迟的。延迟意味着在首次访问数据库之前,不会在数据库上获取锁。因此,对于延迟事务,BEGIN语句本身对文件系统不执行任何操作。在第一次读取或写入操作之前不会获取锁定。对数据库的第一次读取操作会创建一个SHARED锁定,第一次写入操作会创建一个RESERVED锁定。因为锁的获取被推迟到需要它们,所以另一个线程或进程可能会创建一个单独的事务并在当前线程上的BEGIN执行后写入数据库。如果事务是立即的,则只要执行BEGIN命令就会在所有数据库上获取RESERVED锁,而无需等待数据库的使用。在BEGIN IMMEDIATE之后,没有其他数据库连接可以写入数据库或执行BEGIN IMMEDIATE或BEGIN EXCLUSIVE。但是,其他进程可以继续从数据库中读取。独占事务导致在所有数据库上获取EXCLUSIVE锁。在BEGIN EXCLUSIVE之后,除了read_uncommitted连接之外,没有其他数据库连接能够读取数据库,并且没有其他任何连接的连接都能够在事务完成之前编写数据库。
https://www.sqlite.org/lang_transaction.html
Android API提供了一种处理这些交易模式的方法,因此请选择更适合您应用的方式。
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html