Precondition checks and atomic
I often have to check the current value of a resource object in the DB as part of precondition checks of an action (e.g. when updating a "status" column I have to make sure it has a specific value before doing it).
At first I tried to use "validation" for this but that seems to be only for input arguments and input attributes.
So instead I used "change before_action" hooks to load the existing record and add an error to the Changeset if needed.
This works but Ash is complaining that it cannot run it as "atomic" so it needs "require_atomic? false".
I find this a bit confusing as the docs on changeset hooks imply that "before_action" is run within the transaction.
Am I wrong to assume that "atomic" and "transactional" are the same thing in Ash? Is "before_action" executed outside the DB transaction?
I couldn't find a clear answer how to do this properly (as in idiomatic Ash and it being transactional)
5 Replies
atomic and transactional are not the same thing in general, unless you are using serializable transaction isolation levels, which you don't want to do typically.
https://hexdocs.pm/ash/update-actions.html#fully-atomic-updates
That's not really what I was getting at but I was probably not clear enough. I haven't found those specific docs for some reason, thanks.
Here's what I'm currently doing:
Is this idiomatic (enough)? Should I use "validation" instead for fetching and checking the current state? Does the "before_action" run it in the same transaction as the "set_attribute" part or was that just a wrong assumption on my part?
Yep, they run in the same transaction. It is transactional, but not atomic
If you ran that action in parallel, depending on the timing, each action could see a different or the same ticket status depending
Well, sorry, in this example what. i mean is that they could both "do their work" under the impression that they were the ones closing the ticket
Because one transaction and a concurrent transaction running, doing the same thing, will both observe old state.
If you made the action fully atomic, then you would have no possibility of a race condition
Thanks, I will look into atomics in more detail when I really need them
It's totally okay to set
require_atomic? false
and move on with your life, just a helpful indicator you might need to do something