Clojure并发编程:STM与Vars的深度解析
1. STM的使用注意事项
1.1 副作用函数的严格限制
在事务范围内,仅应执行可安全重试的操作,许多I/O操作都被排除在外。例如,在 dosync 块内尝试写入文件或数据库,很可能会多次将相同数据写入文件或数据库。Clojure无法检测到你在事务内执行了不安全的操作,它会愉快且默默地重试这些操作,可能导致灾难性结果。
为了避免这种情况,Clojure提供了 io! 宏,如果在事务内对其求值,会抛出错误。示例代码如下:
(defn unsafe
[]
(io! (println "writing to database...")))
;= #'user/unsafe
(dosync (unsafe))
;= #<IllegalStateException java.lang.IllegalStateException: I/O in transaction>
此外,对原子的操作通常应被视为有副作用的,因为 swap! 等操作不参与STM的事务语义。如果一个事务重试三次,并且包含 swap! 调用, swap! 将被调用三次,受影响的原子将被修改三次。
1.2 引用值的不可变性
引用(refs)持有的值必须是不可变的。虽然Clojure不会阻止你将可变对象放入引用中,但重试和与可变性相关的常见问题
超级会员免费看
订阅专栏 解锁全文
71

被折叠的 条评论
为什么被折叠?



