androiddatabaseandroid-roomcallable

Returning value from runInTransaction() In Android Room database


There is not much documentation to understand how exactly does runInTransaction() method works. While executing multiple operations on different DAO's if no value is to be returned I could use runInTransaction(Runnable body) OR runInTransaction(Callable<V> body) if any result is to be returned.

Query that I have: If all the queries in the transaction are successful, then I want to return an image object that needs to be uploaded to a server on successful transaction If any exception occurred or the transaction was not successful I need to return a boolean with false to indicate the user that some error occurred.

Here is the method:

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;
}

In the above method, what I intend to do is, if all the database executions are a success I need to return an image which will be uploaded to the server. If there is any exception that occurred or any error occurred while doing the db transaction I need to return false to let user know an error occurred. Not sure if I got it right. Also, should I be putting the runInTransaction in try catch block ?


Solution

  • The code for runInTransaction(Callable) is equivalent to the runInTransaction(Runnable) version:

    The main functional difference is that runInTransaction(Callable) returns the value returned by the Callable.

    So, your code can do two things:

    The second solution (easier for me to show you the code given I don't have the code for the method calling to userCheckedIn(User)) will look similar to this:

    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;
    }