I have implemented my following retry logic for “Transaction has been aborted. Please retry”. Can someone suggest if there is a better way or should this work fine in PRODUCTION environment?
func Create(ctx context.Context, data interface{}, id string, entityType string) (string, error) {
setBytes, err := json.Marshal(data)
if err != nil {
log.Printf("Error marshalling data: %v with error: %v", data, err)
return "FAILURE", err
}
var query string
switch entityType {
case "STORE":
query = `query {
v as var(func: eq(store.storeid, "` + id + `"))
}`
case "INVENTORY":
query = `query {
v as var(func: eq(inventory.inventoryid, "` + id + `"))
}`
}
mu := &api.Mutation{
SetJson: setBytes,
}
req := &api.Request{
Query: query,
Mutations: []*api.Mutation{mu},
CommitNow: true,
}
// data persistence with retry
for i := 0; i < maxRetry; i++ {
_, err = dGraphStore.NewTxn().Do(ctx, req)
if err != nil {
log.Printf("Error persisting data %v in Dgraph: %v ", data, err)
} else {
log.Printf("Successfully persisted data %v in Dgraph. Retry: %d", data, i)
return "SUCCESS", nil
}
}
log.Printf("Failed to persist in %d retries", maxRetry)
return "FAILURE", err
}
Inventory gets uploaded in bulk and this method gets called in quick succession.
data is basically either the INVENTORY
or the STORE
struct that has been predefined in the models.
We have the following predicates (inventory.inventoryid is unique to INVENTORY and store.storeid is unique to STORE)
Schema: store.storeid: string @index(hash) @upsert . inventory.inventoryid: string @index(hash) @upsert .
,
Even with keeping maxRetry count as 3, I am seeing 1-5 percent of the inventory updates failing (even after maxRetries)
Please suggest/comment