สมมติว่าคุณมีบัญชีธนาคาร:
(def accounts
[(ref 0)
(ref 10)
(ref 20)
(ref 30)])
และฟังก์ชั่น "ถ่ายโอน" ของอะตอม:
(defn transfer [src-account dest-account amount]
(dosync
(alter dest-account + amount)
(alter src-account - amount)))
ซึ่งทำงานดังนี้:
(transfer (accounts 1) (accounts 0) 5)
(map deref accounts)
=> (5 5 20 30)
จากนั้นคุณสามารถเขียนฟังก์ชั่นการโอนเงินเพื่อสร้างธุรกรรมระดับที่สูงขึ้นได้อย่างง่ายดายตัวอย่างเช่นการโอนจากหลายบัญชี:
(defn transfer-from-all [src-accounts dest-account amount]
(dosync
(doseq [src src-accounts]
(transfer src dest-account amount))))
(transfer-from-all
[(accounts 0) (accounts 1) (accounts 2)]
(accounts 3)
5)
(map deref accounts)
=> (0 0 15 45)
โปรดทราบว่าการถ่ายโอนหลายรายการทั้งหมดเกิดขึ้นในธุรกรรมเดียวแบบรวมกันนั่นคือเป็นไปได้ที่จะ "เขียน" ธุรกรรมเล็ก ๆ
เมื่อต้องการทำสิ่งนี้ด้วยการล็อกจะมีความซับซ้อนอย่างรวดเร็ว: สมมติว่าบัญชีที่จำเป็นต้องถูกล็อคเป็นเอกเทศจากนั้นคุณจะต้องทำอะไรบางอย่างเช่นการสร้างโปรโตคอลตามคำสั่งซื้อล็อคเพื่อหลีกเลี่ยงการหยุดชะงัก มันง่ายมากที่จะทำผิดพลาดที่ตรวจจับได้ยาก STM ช่วยคุณประหยัดจากความเจ็บปวดทั้งหมด