In my application logs I am seeing a few errors like this: rpc error: code = Aborted desc = Transaction has been aborted. Please retry. However, my retry code never gets called, leading me to think that y.ErrAborted check is not working the way I expect from the docs. Is it returning the wrong error?
My code:
for i := 0; i < maxRetries; i++ {
_, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
if err == y.ErrAborted {
// This never gets called
sleep := time.Duration(time.Duration(rand.Intn(10)) * time.Second)
logger.Warn("mutation aborted, retrying...", zap.Error(err), zap.Duration("retry-in", sleep), zap.Int("attempt", i))
time.Sleep(sleep)
} else {
logger.Error("error mutating graph", zap.Error(err), zap.Int("attempt", i))
break
}
} else {
// mutation was successful.
break
}
Looks alright to me. The issue might be clearer with a full code example. For instance, it’s not clear if the mutations you’re running are being committed by .Commit(ctx) or by setting CommitNow: true in the mutation.
I am setting CommitNow: true as part of the mutation, but I thought those were equivalent. The problem is that the if statement never evaluated to true.
mu := &dgoapi.Mutation{
Set: nQuads,
CommitNow: true,
}
It seems to me like the error is about aborted transactions, but the if err == y.ErrAborted { ... } statement never fires. The error I get in dgo is: rpc error: code = Aborted desc = Transaction has been aborted. Please retry. Since the return code from Mutate() is Aborted, I think it is about aborted transactions.
y.ErrAborted is emitted by txn.Commit() not by txn.Mutate(). We’ll need to change Mutate() to do that, which IMO seems reasonable. In the meantime I’d recommend to use Commit() to get the response that you need. If you can notice in the example code, it’s using Commit().
Yes, the second one catches the error correctly. Note that you can also do string index lookup to check for commit abort in the first case right now as well. Saves you a roundtrip for the extra commit call.