liveBook · Manning

Dosync

As explained in Clojure: The Essential Reference

dosync is a Clojure macro that executes forms within a software transactional memory transaction without options.

dosync executes forms within a Clojure software transactional memory transaction. It coordinates changes to multiple refs without requiring explicit locks, and returns the transaction’s final expression. section 14.4

Coordinating an account transfer

Use alter on both refs so the balance changes belong to one transaction: (transfer 300) returns {:account-1 700, :account-2 800}. section 14.4

Within dosync, common transactional operations include:

  • alter and ref-set update ref values. section 14.4
  • commute supports concurrent counter-style updates, while ensure protects a ref read. section 14.4
  • I/O side effects are rejected inside a transaction. section 14.4
(def account-1 (ref 1000)) ; #1
(def account-2 (ref 500))

(defn transfer [amount]
  (dosync ; #2
    (when (pos? (- @account-1 amount))
      (alter account-1 - amount) ; #3
      (alter account-2 + amount))
    {:account-1 @account-1 :account-2 @account-2}))

(transfer 300) ; #4
;; {:account-1 700, :account-2 800}

Trace a complete dosync transaction from ref creation through conditional transfer and returned balances. section 14.4

How Clojure: The Essential Reference covers it

How deep it goes
Defines an optionless sync wrapper and demonstrates updates, concurrent operations, return values, and rejected I/O.
Examples
Uses bank transfers, counters, vote counting, conditional honeypot detection, and an I/O exception.
What you can do after
Apply it via Clojure’s STM to coordinate consistent updates across refs.
How it connects
Connects refs with software transactional memory, alter, commute, ensure, ref-set, sync, and I/O restrictions.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.