How to enable Objectify XA transaction?

2019-07-07 10:24发布

I'm implementing friendship functionality between entities of same type Profile. This entity kind is root (non parent) entity. A Profile has a Set<Ref<Profile>> field named friends and it's getter getFriends().

Here the code:

public boolean makeFriends(final Profile profile1, final Profile profile2) {
    final Ref<Profile> profileRef1 = Ref.create(profile1);
    final Ref<Profile> profileRef2 = Ref.create(profile2);

    boolean result = false;

    // test to avoid useless transaction
    if (!profile1.getFriends().contains(profileRef2) && !profile2.getFriends().contains(profileRef1)) {
        // add to friends (Set<Ref<Profile>>) the Ref of each other
        result = ofy().transact(new Work<Boolean>() {
            @Override
            public Boolean run() {
                profile1.getFriends().add(profileRef2);
                profile2.getFriends().add(profileRef1);
                ofy().save().entities(profile1, profile2).now();
                return true;
            }
        });

    }
    return result;
}

This code give me a:

java.lang.IllegalArgumentException: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXG

even if Objectify documentation says:

Objectify requires no special flags to enable cross-group transactions. If you access more than one entity group in a transaction, the transaction with be an XG transaction. If you do access only one, it is not. The standard limit of 5 EGs applies to all transactions.

So, why my transaction fails?

My code should involve two entity groups (one for each Profile), so behind the limit of 5. Looking at TransactionOptions.Builder.withXG documentation, i should call TransactionOptions.Builder.withXG(true); before. This method returns a TransactionOptions but i don't know a method to pass it!

Thanks in advance

2条回答
放我归山
2楼-- · 2019-07-07 10:36

Objectify always turns on XG transactions if the environment supports it.

Most likely, you're running a test case without the HRD enabled. You must do this explicitly in your LocalDatastoreServiceTestConfig; check the Local Unit Testing docs. If you are getting this message in the dev instance, make sure to check the "Use HRD" checkbox in the eclipse project preferences.

查看更多
Emotional °昔
3楼-- · 2019-07-07 10:36

Make sure you activated the HRD in the local AppEngine for testing, using the VM flag:

-Ddatastore.default_high_rep_job_policy_unapplied_job_pct=1
查看更多
登录 后发表回答