3

I really like STMs, but am hoping to get some advice about how to use transactions properly, especially when one block of transactions depends on another

for example I have some code:

(defn unschedule-task [tt task-id]
  (dosync
   (doseq [entry .....]
    (tk/kill-all! (:task entry)))
   (v/delete! tt [[:task :id] task-id])))

(defn schedule-task [tt task schedule & [enabled? optt]]
  (dosync
   (unschedule-task tt (:id task))
   (v/insert! tt {.....})))

Basically, unschedule-task has a dosync block, and schedule-task calls unschedule-task in its own dosync block as it needs both the deletion and the insertion to go through in one transaction.

How far can one push this and what are the pitfalls to avoid? (I'm thinking there may be issues with circular dependencies but can't think of an example off the top of my head....)

zcaudate
  • 13,998
  • 7
  • 64
  • 124
  • I believe this answer will be helpful. http://stackoverflow.com/questions/2841750/how-do-nested-dosync-calls-behave – mobyte Nov 19 '12 at 01:39
  • Ending a function name with an exclamation mark is used to indicate it may be unsafe to use within an STM transaction due to retries, e.g., `swap!`. – Alex Taggart Nov 19 '12 at 06:07
  • Thanks for the advice! I spent about half a day deleting exclamation marks from my code. Where can we find other conventions like this? – zcaudate Nov 21 '12 at 05:29

1 Answers1

1

transactions are flattened; starting a new transaction during a transaction doesn't do anything. IOW, either all ref modification succeed during the outer transaction or the whole outer transaction is restarted. This means there should be no dependency issues.

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53