3.1 本地事务
本地事务(Local Transaction)其实应该翻译成“局部事务”才好与稍后的“全局事务”相对应,不过现在“本地事务”的译法似乎已经成为主流,这里也就不去纠结名称了。本地事务是指仅操作单一事务资源的、不需要全局事务管理器进行协调的事务。在没有介绍什么是“全局事务管理器”前,很难从概念入手去讲解“本地事务”,所以这里先暂且将概念放下,等读完3.2节后再来对比理解。
本地事务是一种最基础的事务解决方案,只适用于单个服务使用单个数据源的场景。从应用角度看,它是直接依赖于数据源本身提供的事务能力来工作的,在程序代码层面,最多只能对事务接口做一层标准化的包装(如JDBC接口),并不能深入参与到事务的运作过程中,事务的开启、终止、提交、回滚、嵌套、设置隔离级别,乃至与应用代码贴近的事务传播方式,全部都要依赖底层数据源的支持才能工作,这一点与后续介绍的XA、TCC、SAGA等主要靠应用程序代码来实现的事务有着十分明显的区别。举个例子,假设你的代码调用了JDBC中的Transaction::rollback()方法,方法的成功执行也并不一定代表事务就已经被成功回滚,如果数据表采用的引擎是MyISAM,那rollback()方法便是一项没有意义的空操作。因此,我们要想深入讨论本地事务,便不得不越过应用代码的层次,去了解一些数据库本身的事务实现原理,弄明白传统数据库管理系统是如何通过ACID来实现事务的。
如今研究事务的实现原理,必定会追溯到ARIES理论[1](Algorithms for Recovery and Isolation Exploiting Semantic,ARIES),直接翻译过来是“基于语义的恢复与隔离算法”。
ARIES是现代数据库的基础理论,就算不能称所有的数据库都实现了ARIES,至少可以称现代的主流关系型数据库(Oracle、MS SQLServer、MySQL/InnoDB、IBM DB2、PostgreSQL,等等)在事务实现上都深受该理论的影响。在20世纪90年代,IBM Almaden研究院总结了研发原型数据库系统“IBM System R”的经验,发表了ARIES理论中最主要的三篇论文[2],其中“ARIES:A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging”[3]着重解决了ACID的两个属性——原子性(A)和持久性(D)在算法层面上的实现问题。而另一篇“ARIES/KVL:A Key-Value Locking Method for Concurrency Control of Multiaction Transactions Operating on B-Tree Indexes”[4]则是现代数据库隔离性(I)奠基式的文章。下面,我们先从原子性和持久性说起。
[1] ARIES理论:https://en.wikipedia.org/wiki/Algorithms_for_Recovery_and_Isolation_Exploiting_Semantics。
[2] 这个系列的第三篇是“ARIES/lM:An Efficient and High Concurrency Index Management Method Using Write-Ahead Logging”,本文不会涉及。
[3] 下载地址:https://cs.stanford.edu/people/chrismre/cs345/rl/aries.pdf。
[4] 下载地址:http://vldb.org/conf/1990/P392.PDF。