Here is an example of the `try' operator. From the documentation:
"Return a transaction that executes the transactions in BODY atomically until one succeeds.
The return value of the transaction is the value of the transaction that succeeds."
Here we have two counters *c1* and *c2*.
(defvar *c1* (new 'counter)) (defvar *c2* (new 'counter)))
STM> (perform (try (increment *c1*) (increment *c2*))) [debugging output elided...] STM> (values (value-of (count-of *c1*)) (value-of (count-of *c2*))) 1 0
Here, the first transaction (increment *c1*) succeeds, and we're done. Thus the values of the counters are 1,0 respectively. This is what happens when we can't increment *c1*.
STM> (acquire-lock (lock-of (count-of *c1*))) T STM> (perform (try (increment *c1*) (increment *c2*))) [debugging output elided...] STM> (values (value-of (count-of *c1*)) (value-of (count-of *c2*))) 1 1
Since the first transaction (increment *c1*) failed, the second one (increment *c2*) was run and succeeded. So far the behaviour of `try' is very similar to the `or' operator. Now what happens when we can't increment either counter?
STM> (acquire-lock (lock-of (count-of *c2*))) T STM> (perform (try (increment *c1*) (increment *c2*))) [debugging output elided...] STM> (values (value-of (count-of *c1*)) (value-of (count-of *c2*))) 1 1
The values are still the same as before. However the transaction is still waiting for either *c1* or *c2* to be freed. Here is what happens when we free *c2* and notify the threads waiting on it:
STM> (release-lock (lock-of (count-of *c2*))) NIL STM> (unwait (count-of *c2*)) [debugging output elided...] STM> (values (value-of (count-of *c1*)) (value-of (count-of *c2*))) 1 2
The whole transaction has been retried from the beginning. The first counter was still locked so the transaction (increment *c1*) failed. The second transaction (increment *c2*), succeeded.
Whenever a variable is written to memory (when a log is committed), all threads waiting on that variable are woken up automatically with `unwait'. See the code in the `commit' function for more details. That guarantees that transactions eventually commit.
Hoan