I was uploading data to dgraph server and was committing after every 100 records (Java code provided below ) . During the same time, i tried to index a column which failed initially saying they were pending transactions but after 2 - 3 retries, it succeeded .
But due to this, my upload transaction failed giving the below message :
Exception in thread “main” io.dgraph.TxnFinishedException: Transaction has already been committed or discarded
at io.dgraph.AsyncTransaction.commit(AsyncTransaction.java:197)
at io.dgraph.Transaction.lambda$commit$3(Transaction.java:98)
at io.dgraph.ExceptionUtil.withExceptionUnwrapped(ExceptionUtil.java:27)
at io.dgraph.Transaction.commit(Transaction.java:96)
at com.dgraphj.client.App2.main(App2.java:102)
There are currently two approaches i am evaluating :
Using a mq for sending out transactions hence maintaining order
Maintaining a transaction (distributed transaction) fault tolerant system which retries basis on the failure reason hence kind of a thread pool to submit these transactions and then retrying basis on the exception type
For bulk upload, maintaining a smaller window of commit and defining a better strategy for last checkpoint revert and retry . PS: Cannot rely on using Bulk upload since we do not have explicit instructions on what will be the nature of data upload ( PURE INSERT or UPDATE+INSERT)
Some pointers:
You could use the request class, which as a addMutation(Collection) option. This will go well with the kind of loop structure you have and you could have a tight code around opening a transaction, passing a collection (100 records each), and committing. The same collection will also help you with the tailing records that might not go into the commit if clause.
The schematic of the ideal transaction is as below. Please note that there is no commit in the finally clause. Please try to follow this. I feel there is a bug in the code, and it will help you debug it out.
try {
// …
// Perform any number of queries and mutations
// …
// and finally …
txn.commit()
} catch (TxnConflictException ex) {
// Retry or handle exception.
} finally {
// Clean up. Calling this after txn.commit() is a no-op
// and hence safe.
txn.discard();
}
Will try this out to see which of my problems are getting solved .
Can you please help me with the following analogy "If a lot of transactions are submitted, then the transaction (among all submitted) on same key that will be committed will be chosen basis on the smallest timestamp
Assumption : We have n clients firing n transaction at the same time on the same key