Exemple de composabilité de la mémoire transactionnelle logicielle

11

L'un des principaux avantages de la mémoire transactionnelle logicielle qui est toujours mentionné est la composabilité et la modularité. Différents fragments peuvent être combinés pour produire des composants plus gros. Dans les programmes basés sur les verrous, ce n'est souvent pas le cas.

Je cherche un exemple simple illustrant cela avec du code réel. Je préférerais un exemple à Clojure, mais Haskell va bien aussi. Points bonus si l'exemple présente également un code basé sur un verrou qui ne peut pas être composé facilement.

dbyrne
la source
1
Intéressant, mais ressemble plus à une question StackOverflow pour moi.
Steve
Cette question y a été posée 4 minutes plus tard. stackoverflow.com/questions/5518546/… Est-ce que quelqu'un migrerait et fusionnerait cette question (si possible)?
Job
Ouais après l'avoir posté ici, j'ai réalisé que ce serait probablement mieux sur Stackoverflow. Si quelqu'un peut le fusionner, c'est très bien avec moi.
dbyrne

Réponses:

9

Supposons que vous ayez des comptes bancaires:

(def accounts 
 [(ref 0) 
  (ref 10) 
  (ref 20) 
  (ref 30)])

Et une fonction atomique de "transfert":

(defn transfer [src-account dest-account amount]
  (dosync
    (alter dest-account + amount)
    (alter src-account - amount)))

Qui fonctionne comme suit:

(transfer (accounts 1) (accounts 0) 5)

(map deref accounts)
=> (5 5 20 30)

Vous pouvez ensuite facilement composer la fonction de transfert pour créer une transaction de niveau supérieur, par exemple le transfert à partir de plusieurs comptes:

(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)

Notez que tous les transferts multiples ont eu lieu dans une seule transaction combinée, c'est-à-dire qu'il était possible de «composer» les transactions plus petites.

Faire cela avec des verrous se compliquerait très rapidement: en supposant que les comptes devaient être verrouillés individuellement, vous devriez faire quelque chose comme établir un protocole sur l'ordre d'acquisition des verrous afin d'éviter les blocages. Il est très facile de faire une erreur difficile à détecter. La STM vous sauve de toute cette douleur.

mikera
la source