Clojure’s STM provides (through ref and dosync ) a transaction context in which all updates are guaranteed to be “at the same time” with all links linked to the outside world.
The goal is to maintain consistent values in the system; a typical example is the transfer of money between two bank accounts. If you transfer, say, $ 100 from account A to account B, then you want the amounts for A and B to change at the same time.
In this example, there is virtually no ambiguity in the values read for the amounts that are processed inside the transaction, since at the moment only the following situations are possible: reading from outside the transaction:
- The transaction has begun, but not yet completed, so the values have not been “officially” changed. Subsequently, the transaction can be committed or repeated, but when you read them, this is the state of each account.
- The transaction is completed, therefore, the read amounts are changed values.
Within a transaction, the ref that you are only reading (and not changing) can change its value from one point in the transaction to another, this is called write skew (see Clojure Programming - Chapter 4, Refs, Write Skew). To avoid this, you can use ensure (instead of deref ), this will cause if the value for any of these ref changes (the ones you are only reading), then the whole transaction will be retried.
source share