Transactions with single mutations failing

Hey all,

For my demo project I need to update the same nodes often, possibly multiple times per second and I am getting a lot of “Transaction has been aborted. Please retry” errors (I use dgo) even when few/single transactions are running concurrently and all transactions only contain a single mutation, with commitNow enabled.

Am I correct in assuming this is because multiple transactions for the same nodes are detected and dgraph automatically aborts some of these transactions?

My transaction only consist of a single mutation and the response I give to users is based on the data returned by the query in the mutation. Is there a way to ensure these mutations get executed, I do not care about the exact order they are executed in; just that they get executed without having to retry many times.

Furthermore, it appears that a small amount of transactions succeed without actually updating the data. I’m still trying to confirm this behavior though, since it could well be a case of pebkac.

Hi @tuupke, yes, when two transactions are overlapping (mutating same edge etc.), one of them is aborted with TxnConflictException . Since you do not care about order, you could retry with exponential backoff with some jitter to spread out the retrying transactions. We have found that given enough retries, and spacing between transactions, the transaction reliably goes through. Dgraph transactions do commit durably, please do share if you see any issues there.

Hey @anand,

Thank you for the prompt response!

That’s what I thought, which is somewhat unfortunate, but with the random backoff it should be workable.

On the transactions front, I have managed to figure out I had some errors, but now I’m getting different odd behaviour. Is it possible that when a transaction containing multiple mutations gets aborted, some of the mutations are not rolled back?

As per the doc,

When a transaction is aborted, all its changes are discarded. Transactions can be manually aborted.

https://dgraph.io/docs/master/clients/#transactions

Per the design of transactions, it should not happen that only some mutations get rolled back. I found that incorrect use of the client api results in unforeseen issues. For example if we mix NewReadOnlyTxn() along with normal transactions, results would be perceivable as inconsistent, but not actually so. Please do have a close look at the code around transactions.