我有一个长时间运行的操作,我在后台线程中执行。由于操作要么成功完成或者根本不成功,我将整个操作包装在一个事务中。
UI的各个方面在此期间需要对数据库进行只读访问。为了避免阻止UI,我正在尝试在后台操作的主循环中插入对db.yieldIfContendedSafely()
的调用。
这就是我想要的,因为UI不再被阻止,但如果这样做有可能导致数据完整性丢失,那么我并不完全清楚。
yieldIfContendedSafely()
的javadoc说:
暂时结束事务以允许其他线程运行。该 到目前为止,交易被认为是成功的。不要打电话 setTransactionSuccessful在调用之前。当这返回一个新的 事务已创建但未标记为成功。这个 假设没有嵌套事务(beginTransaction有 只被调用一次)并且如果不是那么会抛出异常 情况下。
这是否意味着我的长时间运行操作实际上是以单独的块提交到数据库,或整体事务是否保持足够的状态以最终一次提交整个数据,从而保持数据完整性?
答案 0 :(得分:9)
这是否意味着我的长时间运行操作实际上是以单独的块提交到数据库
是。在yieldIfContendedSafely()
内,Android调用setTransactionSuccessful()
,endTransaction()
,并开始新的事务 - 在此过程中提交您的语句。没有机制在结束后回滚“真实”交易。
仅当另一个线程在数据库上等待时才会出现此行为,否则yieldIfContendedSafely()
不执行任何操作。
我通过以下方案检查了这一点。我启动了两个线程:一个使用事务将数据插入表中,另一个从同一个表中读取数据。该事务没有调用setTransactionSuccessful()
所以通常一切都在最后回滚,使表空。我添加了对yieldIfContendedSafely()
的调用,之后表格不为空并且有来自交易的数据。