Pergunta

O que acontece quando você cria chamadas do Dosync aninhadas? As sub-transações serão concluídas no escopo dos pais? Essas sub-transações são reversíveis se a transação pai falhar?

Foi útil?

Solução

Se você quer dizer ninho sintático, a resposta é depende se o interno dosync vai correr no mesmo fio que o externo.

Em Clojure, sempre que um dosync O bloco é inserido, uma nova transação é iniciada Se alguém ainda não está funcionando neste tópico. Isso significa que, enquanto a execução permanece em um único encadeamento, pode -se dizer que as transações internas são incluídas por transações externas; No entanto, se a dosync ocupa uma posição sintaticamente aninhada dentro de outro dosync, mas por acaso foi lançado em um novo thread, ele terá uma nova transação para si mesma.

Um exemplo que (espero) ilustra o que acontece:

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

A transação "interna" experimenta após a impressão :foo; A transação "externa" nunca precisa reiniciar. (Observe que depois disso acontece, rA cadeia de história é cultivada, então se o "grande" dosync a forma foi avaliada pela segunda vez, o interno dosync não tentaria novamente. Ainda não seria fundido no exterior, é claro.)

Aliás, Mark Volkmann escreveu um artigo fantástico sobre Clojure's Memória transacional de software; É uma leitura altamente recomendada para qualquer pessoa interessada em obter uma visão sólida de detalhes desse tipo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top