事务是一个常见的概念,是对程序运行时异常数据处理的抽象,把多个读写规则抽象成一个操作单元,要么全部成功(commit),要么全部失败(rollback);失败后可以安全地重试。事务使程序无需关心系列操作部分失败的情况,但是否需要事务、如何做事务的并发处理,需要对其有深入理解。
ACID特性
一直觉得ACID中的C的定义很牵强。
原子性(Atomicity)
原子是化学中的概念,指无法再切分的粒度。在多线程中,一个线程执行原子操作,指操作的中间态对其他线程不可见;这和事务中的隔离性类型。
事务的原子性指:在错误时中止,并撤销已经完成的修改。也许可中止性(abortability)更准确。
一致性(Consistency)
一致性比原子性有更多的含义:数据副本的一致性、分区的一致性哈希、CAP的线性化。
事务的一致性:的一组特定陈述必须始终成立,即不变量。
例如,一个借贷系统中,初始借款和放贷金额始终相等;在一系列还款再放贷后的事务操作后,这个等式依旧成立。我认为这点很牵强:一致性的条件是由业务逻辑维护的,由原子性保障实现的。假设贷方账户有1000元,业务代码扣掉这1000元,并打给借方账户1100元,一致性就被破坏了。
事务是数据库提供的特性,所以事务的特性应当是描述数据库本身提供的能力、而非对使用方的约束规范:乔·海勒斯坦(Joe Hellerstein)指出,在论Härder与Reuter的论文中,“ACID中的C”是被“扔进去凑缩写单词的”,而且那时候大家都不怎么在乎一致性。
隔离性(Isolation)
隔离性类似上文提到的多线程原子操作。数据库通常是并发访问的,并发事务也可能操作相同的记录。
事务相互隔离,不会相互冒犯(不能冒犯相对于不可见、不可执行是更广义的隔离,所以有多种事务隔离级别)。狭义的事务隔离性指可序列化,但可序列化会有很大的性能损失,下文会详细讨论事务隔离级别。
持久性(Durability)
持久化是存储系统对业务的承诺,事务的持久性指:一旦commit,写入的数据不会丢失。
没有绝对的持久性,例如所有副本的硬盘都毁掉时。