Room中的RunInTransaction方法

4
我正在努力弄清楚RunInTransaction到底是做什么的。Room文档并没有提供太多信息,只是说“在数据库事务中执行指定的Runnable”。
据我所知:
如果我们有一个异步操作,如查询,然后进行一些插入操作而没有使用runInTransaction
roomDB.runInTransaction(new Runnable() {
    @Override
    public void run() {
          query
    }
});

 insertions
 insertions

runInTransaction函数会在指定操作完成前锁定数据库。因此,在第一次插入时,线程会暂停(请纠正我),直到runInTransaction完成。

我如何控制哪个过程先执行?

但我认为无论如何,数据库都会锁定表格,而不使用runInTransaction方法。如果我错了,请纠正我。

更新

 @Dao
 public interface RepoDao {

    @Query("SELECT * FROM Table")
    LiveData<List<Table>> getAll();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(List<Table> table);
}

主活动

repo = ((BasicApp)getApplication()).getRepository();

repo.insertDataFromNetwork();

((BasicApp)getApplication()).getDatabase().repoMethods()
.getAll().observe(this, new Observer<List<Table>>() {
        @Override
        public void onChanged(@Nullable List<Table> message) {
            Log.d("hello");

        }
    });;

插入来自网络的数据

mDatabase.runInTransaction(new Runnable() {
                   @Override
                   public void run() {

                           mDatabase.repoMethods().insert(....);
                           mDatabase.repoMethods().insert(....);
                           mDatabase.repoMethods().insert(....);
                           mDatabase.repoMethods().insert(....);
                           mDatabase.repoMethods().insert(....);

                       }
                   }
               });
1个回答

4
一次事务代表着在数据库管理系统中对数据库执行的工作单元。(来源:维基百科)
这意味着,如果您例如插入10个用户并更新另外10个用户而不使用runInTransaction方法,Room将把每个插入和更新操作视为单个操作(事务),并且每次都会通知观察Users表更改的观察者。而使用runInTransaction方法执行相同操作将作为一个操作(事务)执行所有更改,并且只会通知一次监听器。
“我如何控制哪个过程先执行?” 只需在单个线程中按顺序运行它们即可。而且不要在主线程中运行数据库事务。

如果我将异步操作和同步操作顺序执行,会出现问题。请参见https://dev59.com/BlcP5IYBdhLWcg3wN3qP - Nick
这是因为如果第二个操作应该在第一个操作之后完成,那么没有人会异步运行两个操作。使用适当的机制 - 等待第一个完成,然后运行第二个。或者在单个线程中同步运行它们。 - Demigod
我刚刚在一个包含实时数据的表中使用runInTransaction进行了10个插入操作,观察者被通知了10次而不是一次。 - Nick
只应该通知一次,你是如何测试的?(可能吗?https://stackoverflow.com/questions/49426306/livedata-observer-is-triggered-during-runintransaction-in-room-database) - Demigod
请参见更新部分。无论是否使用runInTransaction方法,都会插入5个记录,但只会触发2个日志,因为只有最后2个记录才会到达观察者。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接