Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why/When to use realm.beginTransaction? Since there are executeTransaction and executeTransactionAsync

Tags:

android

realm

For instance, if I have this pieces of code:

Realm realm = Realm.getDefaultInstance();

realm.beginTransaction();
mUser.setName("Roy");
realm.commitTransaction();

textView1.setText(mUser.getName());

Based on the document, it says that the Exception will be caught and data won't be persisted if there is an error inside a transaction. So in above code, say if something wrong in mUser.setName("Roy"); or realm.commitTransaction();, there won't be a crash and the code will still continue? However,cancelTransaction isn't called in this case. What will happen? Update: Looks like the app won't crash, but next time if you continue to read something from Realm it will crash and tell you that the Realm is locked, because commitTransaction is not called.

I just cant't figure out in what chances you will use beginTransaction and commitTransaction if there is a risk that errors might happen. There are alreay executeTransaction and executeTransactionAsync can handle it well. Especially with executeTransactionAsync, I guess most of you will use executeTransactionAsync as it has onSuccess and onError.

To me, I can only think of one reason: I want to just do a simple data update and still use the same thread, but in that case I will use below code instead, which is less error-prone.

try {
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            mUser.setName("Roy");
        }
    });
} catch (Exception e) {
    Logger.e(TAG, "error", e);
    Toast.makeText(getActivity(), R.string.error_occurred, Toast.LENGTH_SHORT).show();
    return;
}
like image 238
Arst Avatar asked Sep 28 '16 12:09

Arst


2 Answers

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
       //...
    }
});

is equivalent to

realm.beginTransaction();
try {
    //...
    realm.commitTransaction();
} catch(Throwable e) {
    if(realm.isInTransaction()) {
        realm.cancelTransaction();
    }
    throw e;
}

So if you ask me, begin/commit is error-prone and you shouldn't use it without its catch { cancel.. } clause.

As for not calling cancelTransaction() in case of failure, I just ended up with cryptic issues that stopped happening once I started calling cancelTransaction(), but that was a while ago.

like image 61
EpicPandaForce Avatar answered Nov 15 '22 10:11

EpicPandaForce


This is how I understand that ambiguity:

As EpicPandaForce said in the case "beginTransaction-commitTransaction" you can catch the exception and decide what to do with it, but in the case "executeTransaction" you can't - you can't say to above layer that error was happened.

like image 20
blinker Avatar answered Nov 15 '22 10:11

blinker