The clojure convention for ! is to use it for functions that are not safe to execute in a transaction - that is, functions that cannot safely be retried. That means that most side-effecting functions should end in !, but not necessarily all: it is possible to have side-effecting yet transaction-safe functions as long as the side-effects are idempotent.
When will functions be called in a transaction? STM ref, agent and atom updates.
When will functions be called in a transaction? STM ref, agent and atom updates.