Ejemplo de composibilidad de la memoria transaccional de software

11

Una de las principales ventajas de la memoria transaccional de software que siempre se menciona es la componibilidad y la modularidad. Se pueden combinar diferentes fragmentos para producir componentes más grandes. En los programas basados ​​en bloqueo, este no suele ser el caso.

Estoy buscando un ejemplo simple que ilustra esto con código real. Prefiero un ejemplo en Clojure, pero Haskell también está bien. Puntos de bonificación si el ejemplo también muestra un código basado en bloqueo que no se puede componer fácilmente.

dbyrne
fuente
1
Interesante, pero me parece más una pregunta de StackOverflow.
Steve
Esta pregunta se hizo allí 4 minutos después. stackoverflow.com/questions/5518546/… ¿Alguien migraría y fusionaría esta pregunta (si es posible)?
Trabajo
Sí, después de publicarlo aquí, me di cuenta de que probablemente sería mejor en Stackoverflow. Si alguien puede fusionarlo, está bien conmigo.
dbyrne

Respuestas:

9

Supongamos que tiene algunas cuentas bancarias:

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

Y una función de "transferencia" atómica:

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

Que funciona de la siguiente manera:

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

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

Luego puede componer fácilmente la función de transferencia para crear una transacción de nivel superior, por ejemplo, la transferencia desde varias cuentas:

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

Tenga en cuenta que todas las transferencias múltiples ocurrieron en una sola transacción combinada, es decir, fue posible "componer" las transacciones más pequeñas.

Hacer esto con los bloqueos se complicaría muy rápidamente: suponiendo que las cuentas debían bloquearse individualmente, entonces tendría que hacer algo como establecer un protocolo de orden de adquisición de bloqueos para evitar bloqueos. Es muy fácil cometer un error difícil de detectar. STM te salva de todo este dolor.

mikera
fuente