Одно из главных преимуществ программной транзакционной памяти, которое всегда упоминается, - это возможность компоновки и модульность. Различные фрагменты могут быть объединены для получения более крупных компонентов. В программах, основанных на блокировке, это часто не так.
Я ищу простой пример, иллюстрирующий это с помощью реального кода. Я бы предпочел пример в Clojure, но с Хаскеллом тоже все в порядке. Бонусные баллы, если в примере также показан некоторый код на основе блокировки, который не может быть легко составлен.
Ответы:
Предположим, у вас есть несколько банковских счетов:
И атомная «передаточная» функция:
Который работает следующим образом:
Затем вы можете легко составить функцию переноса, чтобы создать транзакцию более высокого уровня, например, перенос с нескольких учетных записей:
Обратите внимание, что все множественные переносы происходили в одной объединенной транзакции, то есть было возможно «составить» меньшие транзакции.
Сделать это с блокировками очень быстро будет сложно: если учетные записи необходимо заблокировать по отдельности, вам нужно будет сделать что-то вроде установления протокола по порядку получения блокировки, чтобы избежать взаимных блокировок. Сделать ошибку, которую трудно обнаружить, очень легко. СТМ спасает вас от всей этой боли.
источник