About transaction abort error while persist edges

Hello,
I tried multiple thread to persist a list of Edges. While persist edges, each node will be first check existed,
if not existed , then persist the node and later the edge .

I encountered the error:
io.dgraph.TxnConflictException: Transaction has been aborted. Please retry.
	at io.dgraph.DgraphClient$Transaction.checkAndThrowException(DgraphClient.java:315)
	at io.dgraph.DgraphClient$Transaction.commit(DgraphClient.java:256)
	at com.wacai.dgraph.PhoneEdgeDgraphPersister.run(PhoneEdgeDgraphPersister.java:113)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)

Is there any good solution to avoid transaction aborted error?

Thank you very much.

This error is thrown if you are trying to modify the same indexes or data in transactions executing concurrently.

  1. If you are not doing upserts, you could use the IgnoreIndexConflict flag.
  2. Check your schema and remove unnecessary indexes to avoid conflict.
  3. If you are doing upserts, execute the mutation to create the node if it doesn’t with IgnoreIndexConflict as false, then add other edges with IgnoreIndexConflict as true in another mutation.

For example. - You might check if a person exists by checking their email. If it doesn’t, then create a person with the email edge. Then you can get back their uid and add other edges like name, age etc with IgnoreIndexConflict as true.

You can read more about this flag at https://docs.dgraph.io/clients/#run-a-mutation.

1 Like

I use Java client to persist data.
I did not find any existing api to set the IgnoreIndexConflict flag.

You can set it as an option in api.Mutation object dgraph4j/api.proto at master · dgraph-io/dgraph4j · GitHub.

Thank you.

I find the api now.

            public DgraphProto.Mutation.Builder clearCommitNow() {
                this.commitNow_ = false;
                this.onChanged();
                return this;
            }

            public boolean getIgnoreIndexConflict() {
                return this.ignoreIndexConflict_;
            }

            public DgraphProto.Mutation.Builder setIgnoreIndexConflict(boolean value) {
                this.ignoreIndexConflict_ = value;
                this.onChanged();
                return this;
            }

            public DgraphProto.Mutation.Builder clearIgnoreIndexConflict() {
                this.ignoreIndexConflict_ = false;
                this.onChanged();
                return this;
            }

But still does not work.

The schema is : phone_number: string @index(exact), only one index
And my logic to insert an edge is : my code will first check point existed, if not existed try to upset node in transaction. And then query the edge and also upset the edge in transaction.

I could not understand why transaction was aborted while multiple threads are used for upset?

Don’t use IgnoreIndexConflict while doing upserts. If multiple transactions are trying to say set the same phone_number at the same time then one of them will abort. How many phone numbers are you trying to upsert in one mutation? How often are you committing?

For upserts, I would suggest having smaller batch size and committing more frequently to minimize conflicts and hence aborts.

Actually the abort is raised during upsets.
Still I could not find any better solution but catch the exception and re-try several times. It seems works after a lot tests.
I would like to work out any better solution.

While doing upsert getting an error could possibly mean that someone else upserted the node. So you should query again, verify and then try to mutate. See this example dgraph4j/AcctUpsertTest.java at master · dgraph-io/dgraph4j · GitHub

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.