在Android Room数据库中从runInTransaction()返回值

3

目前没有太多的文档来理解runInTransaction()方法的工作原理。当在不同的DAO上执行多个操作时,如果不需要返回值,可以使用runInTransaction(Runnable body);如果需要返回任何结果,则可以使用runInTransaction(Callable<V> body)

我的疑问: 如果事务中的所有查询都成功,则我希望返回一个图像对象,该对象需要在成功事务后上传到服务器。 如果发生任何异常或事务未成功,则我需要返回一个布尔值false,表示用户发生了一些错误。

以下是方法:

public boolean userCheckedIn(final User user) {
    try {
        appDatabase.runInTransaction(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                if (user != null) {

                   //Add entry in table A
                     appDatabase.UserDao().add(user);

                   //Update entry in table B 

                   //Delete an entry from table C 

                    Event image = updateUserAction(action);
                    return image;
                }
                return null;
            }
        });

    } catch (Exception e) {
        return false;
    }
    return true;
}

在上述方法中,我的意图是,如果所有的数据库操作都成功,我需要返回一张图片,这张图片将被上传到服务器。如果在执行数据库事务时出现任何异常或错误,我需要返回false,以让用户知道出现了错误。不确定我是否理解正确。另外,我应该把runInTransaction放在try catch块中吗?
2个回答

5
runInTransaction(Callable) 的代码与 runInTransaction(Runnable) 版本相同:
  • 如果事务成功(即没有抛出异常),则将事务设置为成功状态(通过调用 setTransactionSuccessful()),否则会回滚。
  • 无论如何都会结束事务 (在这一点上,如果它被设置为成功,则整个事务将被提交,否则将被回滚)。
  • 如果在 CallableRunnable 中抛出异常,则不会处理该异常(在 Callable 的情况下会处理,但是会重新抛出)。这意味着您需要在调用 runInTransaction(Callable)runInTransaction(Runnable) 的代码中进行处理。

主要的功能区别是 runInTransaction(Callable) 返回由 Callable 返回的值。

因此,您的代码可以执行以下两件事情:

  • 在成功时返回图像或在失败时返回 null,并在调用 userCheckedIn(User) 方法时上传图像;或者
  • 在您的 userCheckedIn(User) 方法中上传图像。

第二种解决方案(更容易展示给您,因为我没有 userCheckedIn(User) 方法的代码)将类似于以下内容:

public boolean userCheckedIn(final User user) {
    try {
        Event image = appDatabase.runInTransaction(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                if (user != null) {
                    //Add entry in table A
                    appDatabase.UserDao().add(user);

                    //Update entry in table B 

                    //Delete an entry from table C 

                    Event image = updateUserAction(action);
                    return image;
                }
                return null;
            }
        });
        if (image != null) {
            // Upload the image to the server
        } else {
            // No image available (probably because of the "if (user != null)"
            // inside Callable). I assume you want to return false in this case.
            return false;
        }

    } catch (Exception e) {
        return false;
    }
    return true;
}

0

这是另一种方法,只需创建一个包装器方法:

fun <T> runInTransactionValue(
    database: GeneratedDatabase,
    run: Callable<T>,
): T {
    return database.runInTransaction(run)
}

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