 transaction(:Goal, 
:Constraint, +Mutex)
transaction(:Goal, 
:Constraint, +Mutex)
once(Goal)once(Constraint)This predicate is intended to execute multiple transactions with a time consuming Goal in part concurrently. For example, it can be used for a Compare And Swap (CAS) like design. We illustrate this using a simple counter in the code below. Note that the transaction fails if some other thread concurrently updated the counter. This is why we need the repeat/0 and a final !/0. The CAS-style update is in general useful if Goal is expensive and conflicts are rare.
:- dynamic counter/1.
increment_counter(Delta) :-
    repeat,
      transaction(( counter(Value),
                    Value2 is Value+Delta,
                  ),
                  ( retract(counter(Value)),
                    asserta(counter(Value2))
                  ),
                  counter_lock),
    !.