知识卡片
乐观并发控制与悲观并发控制的选择依据
内容
当有些可变数据实在无法隔离时,主要有两种并发控制策略。乐观锁:所有人都能拿到数据的拷贝并自由编辑,谁先完成谁先无阻碍地提交,后完成的人在提交时才会被检测出与已提交修改的冲突,需要自己想办法处理(合并或放弃重做)——可以把乐观锁理解为”关于冲突检测的”策略(尽管它其实不是真正的加锁,但这个叫法太流行以至于无法忽略)。悲观锁:谁先取得数据,别人就不能动它,必须等到锁被释放——可以理解为”关于冲突避免的”策略。两者各有代价:悲观锁的问题是显著削弱并发程度,别人只能干等,对企业数据而言经常连读取都做不到;乐观锁的问题是冲突发生后必须有人去处理合并——源代码这类结构化文本往往能自动合并或至少容易看出差异,但业务数据通常难以自动合并,出现冲突常常只能推倒重来。选择两者的核心标准是”冲突的频率与严重性”:如果冲突很少发生、或者发生了后果也不严重,通常应该选乐观锁(并发性更好、实现也更容易);如果冲突一旦发生会让用户很痛苦(比如已经填了一小时的表单被作废),就应该选悲观锁。但无论选哪一种,都可能引入和原来同样多的新麻烦,不存在无代价的方案。
结构图:
flowchart LR
A["可变数据无法隔离"] --> B["乐观锁<br/>冲突检测<br/>提交时才发现冲突"]
A --> C["悲观锁<br/>冲突避免<br/>取锁独占直到释放"]
B --> B1["优:并发性好/易实现<br/>缺:冲突后需自己合并"]
C --> C1["优:尽早避免冲突<br/>缺:并发度低/实现更难"]
D["选择标准:冲突的频率与严重性"] --> B
D --> C
参考来源
- 位置:《企业应用架构模式》第一部分"表述"之"第5章 并发"之"5.4 乐观并发控制和悲观并发控制"(源文件:_epub-src/OEBPS/Text/000033.html)
- 结论依据:原文说明"如果把乐观锁看作是关于冲突检测的,那么悲观锁就是关于冲突避免的……在乐观锁和悲观锁之间进行选择的标准是:冲突的频率与严重性。如果冲突很少,或者冲突的后果不会很严重,那么通常情况下应该选择乐观锁……但是,如果冲突的结果对于用户来说是痛苦的,那么就需要使用悲观锁策略",直接支撑本卡结构图。
- 原始内容:在乐观锁和悲观锁之间进行选择的标准是:冲突的频率与严重性。如果冲突很少,或者冲突的后果不会很严重,那么通常情况下应该选择乐观锁,因为它能得到更好的并发性,而且更容易实现。