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

在事务运行时读取sqlite数据(Android),android,multithreading,sqlite,android-sqlite,Android,Multithreading,Sqlite,Android Sqlite,我需要从数据库中读取一些数据,同时在另一个带有事务的线程中加载一些数据 所有读取其他表的线程都将停止,直到其他线程中的事务完成 我需要能够从数据库中读取信息,而不必担心其他线程 我已经阅读了很多关于sqlite、android的信息……但是没有任何东西起作用,我读取参数的查询总是被阻止 正如@KevinGalligan在这个线程()中所说,我遵循了这些建议来解决锁和其他问题 1) 我只使用了一个SQLiteOpenHelper(singleton) 2) 我从未关闭过数据库 我试过: 通过以下方

我需要从数据库中读取一些数据,同时在另一个带有事务的线程中加载一些数据

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

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

我已经阅读了很多关于sqlite、android的信息……但是没有任何东西起作用,我读取参数的查询总是被阻止

正如@KevinGalligan在这个线程()中所说,我遵循了这些建议来解决锁和其他问题

1) 我只使用了一个SQLiteOpenHelper(singleton)

2) 我从未关闭过数据库

我试过:

通过以下方式启动事务:

database.execSQL("begin immediate transaction");

反而

database.beginTransaction();
不工作,查询被阻止

我读过关于WAL(database.enableWriteHeadLogging())的文章,但我需要支持API9


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

我认为你应该使用同步概念来避免你所面临的问题。

android中的SQLite it不是线程安全的,当操作执行时,数据库将被锁定,这意味着您应该确保数据库操作只在一个线程中执行,并调用database.setTransactionSuccessful();如果您的数据加载工作不仅仅是一个大型SQL事务,则允许其他线程在不同点读取数据库。因此,例如,如果您正在执行某种批量数据加载,并且每100次插入就执行一次事务,则在每次执行each-100-inserts循环时调用
yieldiffrantedsafely()
,以使其他线程有机会使用数据库。

我解决了这个问题

我遵循这个步骤

要解决数据库锁定和数据库多线程使用问题(基于中):

1) 我只使用一个SQLiteOpenHelper(singleton)

2) 永远不要关闭数据库

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

使用
数据库.enableWriteAheadLogging()
(仅api>=11),我的错误是您必须在所有连接中启用此模式,而不仅仅是在您的事务或书写中,因此我在“onOpen”方法中将以下代码添加到我的openHelper类中。基于github()中Mozilla的这段代码

使用此解决方案,我解决了在更新某些表时阻止读取的问题,但其他更新也被阻止。如果您想解决最后一个问题,正如@commonware所说:

在事务中使用
yieldiffrantedsafely()
可以让其他线程有机会使用数据库。我没有发现使用此方法与
beginTransaction
BeginTransactionNoneExclusive


另一个有趣的阅读是:

我建议在方向上关闭同步SQLITE选项(在Android中默认情况下,当一个写事务操作正在运行其他读数据库查询时,等待完成写事务) 您应该在每次连接到此选项的数据库tyrn之前
db.exeqSql(“PRAGMA synchronous=OFF”)

因此,所有读取操作都将立即执行,但您会从数据库中获得一点过时的数据(您无法在结果数据中看到正在运行的写入事务正在插入数据库)

同步是为了避免竞争条件等…这将给我的案例增加更多的阻塞问题。。。如果我正在更新一个表,我只需要读取一个数据库而不必担心。在这种情况下,您必须输入自己的逻辑。
database.beginTransaction();
@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());
             }
         }
     }