android - 在事务运行时读取 sqlite 数据 (Android)

标签 android multithreading sqlite android-sqlite

我需要从数据库中读取一些数据,同时我正在使用事务在另一个线程中加载一些数据。

我所有读取其他表的线程都停止,直到其他线程中的事务完成。

我需要能够从数据库中读取信息而不用担心其他线程。

我已经阅读了很多关于 sqlite、android 的信息...但是没有任何效果,我读取参数的查询总是被阻止。

我已经按照@KevinGalligan 在此线程 ( What are the best practices for SQLite on Android? ) 中所说的解决锁和其他问题的建议。

1) 我只使用一个 SQLiteOpenHelper(单例)

2) 我从不关闭数据库

我试过:

开始交易:

database.execSQL("begin immediate transaction");

database.beginTransactionNonExclusive();

代替

database.beginTransaction();

不工作,查询被阻止。

我读过有关 WAL(database.enableWriteAheadLogging()) 的信息,但我需要支持 api 9。

在事务更新某些表的同时读取任何其他解决方案?我不在乎我的信息是否被弃用,更重要的是不要阻止我的线程。

最佳答案

我解决了这个问题。

我遵循了这些步骤。

解决数据库加锁和数据库多线程使用问题(引用http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection):

1) 我只使用一个 SQLiteOpenHelper(单例)。

2) 永远不要关闭数据库。

为了能够在不阻塞查询的情况下进行读写,我遵循了以下步骤:

使用database.enableWriteAheadLogging()(仅api>=11),我的错误是你必须在所有连接中启用此模式,而不仅仅是在你的事务或你的写作中,所以我添加了在“onOpen”方法中将以下代码添加到我的 openHelper 类中。基于 github 中的 Mozilla 代码 ( https://github.com/mozilla/mozilla-central/blob/9f2b8297b99d9d28038256b4f92a5aaa941749f1/mobile/android/base/db/TabsProvider.java )。

@SuppressLint("NewApi")
    @Override
     public void onOpen(SQLiteDatabase db) {

         // From Honeycomb on, it's possible to run several db
         // commands in parallel using multiple connections.
         if (Build.VERSION.SDK_INT >= 11) {
             try{
                 db.enableWriteAheadLogging();
             }catch(Exception e){
                 Log.e("onOpen", e.getMessage());
             }
         }
     }

通过这个解决方案,我解决了在更新一些表时阻塞读取的问题,但其他更新也被阻塞了。如果你想解决最后一个问题,正如@commonsware 所说:

在您的事务中使用 yieldIfContendedSafely() 您将为其他线程提供使用数据库的机会。我没有看到将此方法与 beginTransactionbeginTransactionNonExclusive

另一个有趣的读物是:What are the best practices for SQLite on Android?

关于android - 在事务运行时读取 sqlite 数据 (Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636765/

相关文章:

.net - 当另一个线程正在其上执行方法时使对象引用无效 (.NET)

Java JTable 一次将一个单元格保存到数据库中

python - 减少 Django Web 应用程序中 ORM 查询的数量

multithreading - 如何使方案在批处理脚本中发生

java - 如何删除 SQLite 数据库中的条目?

java - android应用程序ArrayList中的错误

android - 使用 Geocoder (Android) 绘制路径有什么限制吗?

android - 根据屏幕尺寸设置 WebView 缩放

java - Android - 获取动态生成的按钮的ID

java - 在线程中使用 Lambda