Welcome! Please see the About page for a little more info on how this works.

0 votes
in Peer API by

It stands to reason that all transactions submitted (via datomic.api/transact) and transacted (demonstrated via deref) on a single peer would be included in all subsequent DB values obtained (via datomic.api/db) on the Peer, but I'd love to know if that is guaranteed.

For example, if a test transacts data resulting in some T, and the rest of the test only cares that it runs against a DB value with T' >= T, is the following sufficient?:

@(datomic.api/transact conn tx) ; T (let [db' (datomic.api/db conn)] ; T' >= T? ,,(do-something-with db')

Or is it strictly necessary to do:

(let [{:keys [db-after]} @(datomic.api/transact conn tx)] ,,(do-something-with db-after))

I know that the former tends to work, but I'm particularly interested if it's guaranteed to work.

I do understand that additional transactions from other threads / clients / etc. may have been included in db' in the first scenario, so I realize the code is not equivalent in the general case. I'm only concerned about tx having been transacted and included in the fetched db' value.

Thank you!

(Apologies for formatting—I can't seem to convince this thing to care about my whitespace.)

1 Answer

0 votes

I believe the reason this "tends" to work is because the connection is a singleton

Datomic connections do not adhere to an acquire/use/release pattern.
They are thread-safe and long lived. Connections are cached such that
calling datomic.api/connect multiple times with the same database
value will return the same connection object.

Based on this, the db acquired from your connection should always be >= the db referenced in any completed transactions that have been confirmed on the same JVM (after all, datomic.api/db does not communicate with the transactor).

So, what is a circumstance where this wouldn't hold? Of course, there could be a communication failure after the transaction is processed but before it is acknowledged...but in that case transact would result in an error.

What about if the Peer implementation changed, such as keeping a connection per thread instead of per JVM...in that case you'd need to sync within the JVM to coordinate this (just as you would in the distributed scenario).

I'd conclude that the guarantee is dependent on an implementation detail (albeit a partially documented one).