Resolve actual IDs from temporary IDs in case of communication failures during transaction executing

Hello, Datomic community,

The documentation (Datomic Deployment | Datomic) mentions that “Not all transactions are idempotent, and transactions may have succeeded, even if the communication back to the peer failed.” This raises the question: How to resolve actual IDs from temporary IDs if a communication error occurs but the transaction may have been successful on the transactor side?

In my case, I need to obtain the entity identifiers created during a transaction. Under normal circumstances, I would use temporary identifiers (Transaction Data | Datomic) to later resolve them to their actual entity IDs using resolve-tempid (datomic.api - Datomic Clojure API documentation).

However, if a communication error occurs but the transaction has succeeded, I would need to repeat the transaction on the version of the database that was current just before the transaction was executed. The issue is that the as-of functionality cannot be used for branching (Database Filters | Datomic), which prevents me from repeating the creation of the entity since calling with + as-of leads to an error such as:

:db.error/unique-conflict Unique conflict: :myUniqueAttribute, value: 2 already held by: 17592186045515 asserted for: 17592186045517

How can I approach implementing retries while ensuring that I can still get the correct entity identifiers in case of such errors?

Thank you

2 Likes

I guess the only option is to work with a :db.unique/identity attribute for your external identifier. Then you can just retry the transaction and it will do an upsert of the entity with the given identifier if it already exists.