Frage

Was passiert, wenn Sie verschachtelte DoSync Anrufe erstellen? Werden Untertransaktionen im übergeordneten Bereich ergänzt werden? Sind diese Untertransaktionen reversibel, wenn die übergeordnete Transaktion fehlschlägt?

War es hilfreich?

Lösung

Wenn Sie syntaktische Verschachtelung bedeuten, dann ist die Antwort es hängt davon ab, ob der innere dosync auf dem gleichen Thread wie die äußere läuft .

In Clojure, wann immer ein dosync Block eingegeben wird, wird eine neue Transaktion gestartet , wenn man auf diesem Thread nicht ausgeführt worden ist bereits . Dies bedeutet, dass während der Ausführung bleibt auf einem einzigen Faden, können innere Transaktionen gesagt werden durch äußere Transaktionen subsumieren; aber wenn ein dosync eine Position innerhalb eines anderen dosync syntaktisch verschachtelt einnimmt, sondern geschieht in einem neuen Thread gestartet werden, wird es eine neue Transaktion an sich selbst haben.

Ein Beispiel, das (hoffentlich) zeigt, was passiert:

user> (def r (ref 0))
#'user/r
user> (dosync (future (dosync (Thread/sleep 50) (println :foo) (alter r inc)))
              (println :bar)
              (alter r inc))
:bar
:foo
:foo
1
user> @r
2

Die „innere“ Transaktion Wiederholungen nach :foo Druck; die „äußere“ Transaktion muss nie wieder zu starten. (Beachten Sie, dass nach dem dies geschieht, r Geschichte Kette gewachsen ist, so dass, wenn die „große“ dosync Form zum zweiten Mal bewertet wurden, wobei die innere dosync würde Neuversuch nicht. Es wäre immer noch nicht in die Außen eine verschmolzen werden, natürlich. )

Übrigens hat Mark Volkmann einen fantastischen Artikel über Clojure schriftliche Software Transactional Memory ; es ist in hohem Grade für jedermann gewinnen festen Einblick in die Details dieser Art interessiert empfohlen zu lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top