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

advertisements

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 don'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. In this case I will use:

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


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.