知识卡片

业务事务与系统事务的错位

普通读书笔记卡

内容

系统事务——由关系数据库和事务监视器原生支持的那种事务,是一组由明确开始/结束指令界定的SQL命令,只要有一条违反约束就整体回滚,全部成功则同时对外生效——这类事务技术成熟、开发者也很熟悉,几乎不用操心。但系统事务对业务系统的最终用户毫无意义:用户理解的”一个事务”是登录、选账户、填账单、点击确认付款这一整套操作,即业务事务,人们希望它同样具备ACID特性(点确认前的任何屏幕改动都不该产生系统可见的影响)。让业务事务天然具备ACID的最简单办法,是把整个业务事务塞进单个系统事务里执行,但业务事务常常要经过多次请求才能走完,这样实现出来就是一个长系统事务——而大多数事务系统本就不擅长支撑长事务,会让数据库沦为系统的主要瓶颈、丧失可伸缩性;不过如果并发需求确实不高、能承受这个代价,直接用长事务反而是最省事、最不容易出错的方案。撑不住长事务的场景就只能把业务事务拆成一串短系统事务,自己负责把它们”粘合”起来提供跨系统事务的ACID——这正是离线并发问题的由来。业务事务的四个ACID属性里,原子性和持久性相对好实现:只需在用户点”保存”时启动一个系统事务、把所有累积的修改一次性提交并持久化即可(领域模型场景下用工作单元跟踪修改,事务脚本场景下手动跟踪也不复杂,因为逻辑通常足够简单);最难支撑的是隔离性——没有隔离性就谈不上一致性,跨多个系统事务时,既要防止一个会话破坏另一个会话尚未提交的工作,也要提防不同系统事务之间读到互相矛盾的数据。

参考来源

- 位置:《企业应用架构模式》第一部分"表述"之"第5章 并发"之"5.5.4 业务事务和系统事务"(源文件:_epub-src/OEBPS/Text/000038.html) - 结论依据:原文说明"让业务事务支持ACID属性的最简单方法是在单个系统事务中执行完整的业务事务。但是,业务事务常常要通过多次请求才能完成,因此用单个系统事务的实现会产生长系统事务……在这种情况下,只能把业务事务分成一系列的短事务……业务事务的ACID属性中最麻烦的是隔离性。没有隔离性就没有一致性",直接支撑本卡结论。 - 原始内容:事务原子性和持久性是最容易为业务事务所支持的ACID属性……业务事务的ACID属性中最麻烦的是隔离性。没有隔离性就没有一致性。