Fork me on GitHub
#datalevin
<
2024-04-18
>
plexus12:04:44

I'm trying to figure out how to an atomic "read-then-write", the README mentions transaction functions and something called intern-fn, but I can't find any other reference to what this is. Are transaction functions supported?

Huahai16:04:04

Yes, use with-transaction for atomic actions. inter-fn is for cases when the function needs to be serialized, e.g. when trying to save this function in DB as a :db/fn, or pass this function over the wire to server/babashka

Huahai16:04:44

This inter-fn macro is necessary in order to accommodate GraalVM native image, because eval cannot be used in native image, which has a closed world assumption. This macro method is the only way that I come up with that allows serialization of functions without eval . The source code of the function will be interpreted by sci, so there's currently some limitations, e.g. except for built-in ones, Clojure vars are not accessible. We will address these limitations later.

Huahai16:04:43

So if you want to use a stored transaction function using :db/fn it needs to be declared using inter-fn, or definterfn, etc.

Huahai16:04:01

An alternative, is to use :db.fn/call, which does not store the function, so this is usable in embedded mode, where that function is available in your code to call and that function can be a regular Clojure function.

Huahai16:04:02

So there are 3 options, choose the one that works for your use case.

Huahai17:04:29

You can see the use of all these cases in our test suite. For with-transaction, look in datalevin.withtxn-test; for later two cases, look in datalevin.test.transact