4Seven Concurrency Models in Seven Weeks

Clojure的STM

软件事务内存

STM事务MVCC隔离

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第4章:Clojure的STM(软件事务内存)

一、导读

1.1 本章学习目标

第4章深入讲解 Clojure 的 STM(Software Transactional Memory)——一种用数据库事务的思想来解决并发问题的模型。

本章的核心学习目标包括:

  • 理解 STM 的工作原理
  • 掌握 MVCC(多版本并发控制)
  • 理解 STM 的隔离性保证
  • 学会使用 STM 解决复杂的并发问题

1.2 为什么本章如此重要

STM 将数据库事务的概念引入内存操作——原子性、一致性、隔离性。它让并发编程变得像写数据库事务一样简单。理解 STM,能帮你理解分布式系统中的一致性保证。

1.3 核心问题引导

STM 和数据库事务有什么相似之处?

MVCC 是如何实现无锁并发的?

STM 的性能开销有多大?

STM 适合什么类型的问题?


二、核心概念详解

2.1 STM 基础

clojure
;; Ref 是 STM 的核心
(def balance (ref 100))

;; dosync 开启事务
(dosync
  (alter balance - 50))

;; 事务保证:
;; 1. 原子性:要么全部成功,要么全部失败
;; 2. 一致性:事务结束时状态一致
;; 3. 隔离性:并发事务互不干扰

2.2 MVCC

clojure
;; STM 使用 MVCC:每个事务看到一致的快照
;; 如果冲突,事务自动重试

(def x (ref 0))
(def y (ref 0))

;; 事务1:读取 x,修改 y
(future
  (dosync
    (let [x-val @x]
      (Thread/sleep 100)    ;; 模拟长时间操作
      (alter y + x-val))))

;; 事务2:修改 x
(future
  (dosync
    (alter x inc)))

;; STM 自动处理冲突:如果事务1提交时发现 x 已被修改,会自动重试

2.3 validate 函数

clojure
;; 为 Ref 添加验证
(def account (ref 0 :validator #(>= % 0)))

;; 验证失败会抛出异常
(dosync
  (alter account - 100))    ;; 抛出 IllegalStateException

三、实战案例

3.1 案例一:并发计数器

clojure
(def counters (ref (zipmap (range 10) (repeat 0))))

(defn increment [key]
  (dosync
    (alter counters update key inc)))

;; 并发递增
(dotimes [i 1000]
  (future (increment (rand-int 10))))

(Thread/sleep 2000)
(println @counters)

四、本章小结

STM:用事务的方式管理内存操作。

MVCC:多版本并发控制,避免锁的使用。

自动重试:冲突时事务自动重试。

验证器:为 Ref 添加约束条件。


五、思考与练习

STM 的自动重试在什么情况下可能导致问题?

STM 和锁并发相比,性能如何?

设计一个使用 STM 的并发数据结构。


4/7Cloj
0%