2012-02-12 82 views

回答

2

Sqlite does not support nested transactions:使用BEGIN创建

交易...凯明不嵌套。对于嵌套的 事务,请使用SAVEPOINT和RELEASE命令。

我自己在SQLiteDatabase类中使用嵌套事务时遇到了死锁问题,所以我强烈建议您远离嵌套事务。使用自己的锁来防止嵌套事务。

1

在两个单独的线程上创建两个单独的事务不被视为“嵌套事务”。

每个线程都维护自己的数据库会话,该数据库会话映射到0或1个数据库连接(如果会话不再需要连接,则可以从连接池中选择数据库连接并返回给它),因此在任何时间,会话是否有连接,取决于它是否需要)。

因此,每个线程维护其自己的交易状态indepdnent其他线程。来源证实了这一点:

../Android/sdk/sources/android-23/android/database/sqlite/SQLiteDatabase.java:

// Thread-local for database sessions that belong to this database. 
// Each thread has its own database session. 
// INVARIANT: Immutable. 
private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() { 
    @Override 
    protected SQLiteSession initialValue() { 
     return createSession(); 
    } 
}; 

../Android/sdk/sources/android- 23 /安卓/数据库/源码/ SQLiteSession.java:

* <h2>About database sessions</h2> 
* <p> 
* Database access is always performed using a session. The session 
* manages the lifecycle of transactions and database connections. 
* </p><p> 

...

* Consequently, each thread 
* has its own session object and therefore its own transaction state independent 
* of other threads. 

所以,如果你有两笔交易去在单独的线程中,它们不是“嵌套”的,而是完全独立的,并且将根据所涉及的交易的模式和类型(即,不管它们是否被推迟,立即,排他性以及它们是否被读取或写入)。

但是,必须正确使用Android SQLite库来实现此目的。

我有2个线程访问一个数据库连接

如果这意味着两个线程都使用相同的SQLiteSession,(虽然我不知道你怎么能如果它甚至有可能做到这一点),那很可能导致僵局。

我的设置:

  1. 单个内容提供商
  2. 内容供应商初始化成员变量mDbHelper为SQLiteOpenHelper在它的onCreate()
  3. 呼叫mHelper。getReadableDatabase/getWriteableDatabase根据需要在内容提供商的查询/插入/ ...方法
  4. Android将处理确保使用内容提供商

如果长期运行的事务将是每个线程在不同的交易状态在一个线程上执行(例如,从后台线程同步数据导入),考虑使用db.yieldIfContended()db.yieldIfContendedSafely()来允许来自其他线程的事务(比如说或者记录UI线程中的更新)挤入,以便它们不必等待长时间运行事务完成并阻止这些线程。

相关问题