STM и изменить в clojure - PullRequest
       34

STM и изменить в clojure

4 голосов
/ 25 марта 2011

Я работаю с книгой Programj Clojure .Объясняя alter и STM, они говорят, что, если во время изменения Clojure обнаружит изменение ссылки извне транзакции, она повторно выполнит транзакцию с новым значением.Если это так, я полагаю, что функция обновления, которую вы передаете, должна быть чистой, но это не указано в документации (и в других подобных ситуациях).

Так что мое предположение верно?Если нет, то как STM повторно применяет функцию?Если это правильно, то вы не можете полагаться на документы, которые сообщают вам, когда у вас могут быть побочные эффекты, а когда нет?

Ответы [ 3 ]

8 голосов
/ 25 марта 2011

Оно не обязательно должно быть чистым, оно просто должно быть идемпотентом . На практике это одно и то же.

Кроме того, он должен быть только идемпотентным, если смотреть за пределы STM: если единственный побочный эффект, который вы производите, - это запись в какой-либо другой реф или (я думаю) отправка агенту, эта операция будет удерживаться до тех пор, пока ваша транзакция не завершится. удалось.

Это также не тот случай, когда имеет , чтобы быть любой из этих вещей: просто, если ваша функция обновления не чистая, результаты могут не соответствовать вашим ожиданиям.

Edit: dosync документы говорят вам, что любые выражения в теле могут быть выполнены более одного раза. Вы не можете запустить alter без запуска dosync, поэтому, похоже, все необходимые вам документы есть. Что бы вы хотели изменить?

4 голосов
/ 25 марта 2011

Как примечание:

Если вам необходимо выполнить побочные эффекты, такие как регистрация в вашей трансляции STM, вы можете отправлять сообщения агентам для выполнения неидемпотентных частей.Сообщения, отправленные агентам, отправляются только после завершения транзакции и гарантированно будут отправлены только один раз.

1 голос
/ 12 декабря 2011

Суть в Clojure заключается в том, что при работе с транзакциями не возникает побочных эффектов, поскольку они согласованы, и функция будет перезапущена (я предпочитаю повторяться), когда обнаружит конфликт во время обновления общего значенияв противном случае он совершит изменения успешно.Если он должен повторить попытку, он прочитает обновленное значение, поэтому побочный эффект отсутствует, проблема, с которой вы можете столкнуться, - это Livelock, но он в некоторой степени контролируется ограниченным числом при повторных попытках от Clojure.

...