Bazı banka hesaplarınız olduğunu varsayalım:
(def accounts
[(ref 0)
(ref 10)
(ref 20)
(ref 30)])
Ve bir atomik "transfer" fonksiyonu:
(defn transfer [src-account dest-account amount]
(dosync
(alter dest-account + amount)
(alter src-account - amount)))
Aşağıdaki gibi çalışır:
(transfer (accounts 1) (accounts 0) 5)
(map deref accounts)
=> (5 5 20 30)
Daha sonra, daha yüksek düzeyli bir işlem oluşturmak için transfer işlevini kolayca oluşturabilirsiniz, örneğin birden fazla hesaptan transfer:
(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)
Birden çok aktarımın tamamının tek bir birleşik işlemde gerçekleştiğini, yani daha küçük işlemleri "oluşturmak" mümkün olduğunu unutmayın.
Bunu kilitlerle yapmak çok hızlı bir şekilde karmaşık hale gelecektir: hesapların ayrı ayrı kilitlenmesi gerektiğini varsayarsak, kilitlenme emrini önlemek için kilit satın alma siparişinde bir protokol oluşturmak gibi bir şey yapmanız gerekir. Tespit edilmesi zor bir hata yapmak çok kolaydır. STM sizi tüm bu acılardan kurtarır.