- 原子性,事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败;
- 一致性,事务执行后,数据库状态与其它业务规则保持一致;
- 隔离性,指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
- 持久性, 一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据
比较难理解的是一致性的表述。有一种补充解释是一致性保证的是从一种状态到另一种状态的一致维护,而保证不出现中间状态。当注意力放在中间状态时,一致性与隔离性的定义有重叠,当注意力放在两种状态的切换,又与原子性的定义有重叠。所以这样的解释对于深入理解事务的四大特性是不完美的。
四大特性的深入理解
一个完整的事务系统需要数据库,事务框架,业务逻辑三层组成。数据库是事务构成的基石,这也是数据库区别于文件系统的主要特征。在数据库层级上,提供了事务隔离级别的实现。一般的事务隔离级别分为四级
- 读未提交:read uncommitted
- 读已提交:read committed
- 可重复读:repeatable read
- 串行化:serializable
本质上,事务的隔离性是由数据库层级上的隔离级别保证的。持久性也是数据库层级所保证的,这个很容易理解。到了原子性,情况发生了变化。 数据库层级提供了commit 和 rollback 的函数,但是这没有提供全部成功和全部失败的原子性完全保证,仍需要事务框架的支持。这就是事务托管方。事务托管方可以是持久化框架如Mybatis,Hibernate等,也有可能是更高一点的框架,如spring framework,还有一种比较容易被忽视的,就是手动编写的完整的具有事务控制的SQL 脚本,这与其他事务托管方所完成的工作几乎一样。当然最常见的还是spring 的事务模块,在下一篇我们可以对spring 事务的细节展开,这里我们继续扣题发挥。最后就是一致性了。一致性的保证是最特殊的,需要数据库,事务框架,业务逻辑自下而上的共同维护。数据库层级提供持久性和隔离性的保证,并提高原子性的能力与事务框架共同提供原子性保证,基于这些下层能力的基础,才能最终在顶层业务的逻辑层完成一致性的保证。所以一致性是数据库状态与其他业务规则保持一致。
用转账的例子 A账号往B账号里转5000,这时候数据库要执行两行代码: A:减去5000 B:加上5000 这是一致性情况,如果代码为 A:减去5000 B:加上5001 这就是对一致性的破坏。
所以认为隔离性和原子性与一致性是有重叠的,更好的解释是他们的关系是因果的链式关系。再看一下他们”非重叠的部分“
隔离级别在RR以上,一致性和隔离性是”吻合“的,但在RR之下,事务内的中间状态对其他事务而言是暴露的。这是对关于一致性对可见性约束的破坏,另一方面也说明他们管辖范围的不同。至于更多的不同或侧重点不需一一赘言。
这里瞎掰了事务四大特性立体的关系,关于更多或者不同的理解您可以留言讨论。后面关于事务有更多的分析,欢迎拍砖