水平有限,有错误之处望大神们指出,不胜感激
什么是事务
引用《高性能Mysql》中的定义:
事务就是一组原子性的sql查询,或者说一个独立的工作单元。如果数据库引擎能够成功的对数据库应用该组查询。如果其中有任何一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。
事务的特性
- 原子性(Atomicity)
一个事务中的所有sql操作是一个整体,要么全部成功提交,要么全部失败回滚,不允许中间状态。
原子性的语义,只保证记录了回滚段,这个回滚段能够回滚到之前的版本。
为了实现原子性,需要通过undo日志。将所有对数据的更新操作写入日志,如果一个事务中执行了一部分操作,后面的操作由于断电/系统崩溃等其他原因无法继续,则通过回溯日志,将已经执行过的操作撤销,从而达到“全部失败回滚”的目的。
场景:数据库系统崩溃后重启,此时数据库处于不一致的状态,必须先执行一个crash recovery的过程,读取日志进行redo(重新执行将所有已经成功提交但为写入磁盘的操作,保证持久性),再对所有崩溃时未成功提交的事务进行undo(撤销所有执行了一部分但尚未比较的操作,保证原子性)。crash recovery结束后,数据库恢复到一致性状态。 - 一致性(Consistency)
书本定义:数据库总是从一个一致性的状态转换到另一个一致性的状态。
就我个人的理解,事务的ACID中,一致性是最基本的属性,其他的三个属性都是为了保证一致性而存在的。首先我觉得我们可以把数据库的一致性状态和一个事务单元的一致性拆开来说。数据库的一致性就是一个系统的状态,一个合理的状态。而是否合理这表现在这个状态是否符合业务规则。比如说A给B转战,业务要求总额不变,那么这个一致性状态就是总金额相同。当我们的代码中写了A = A-100时,就必须再写上B = B+100才能保证一致性,否则数据库就处于不一致的状态。那么事务单元的一致性是什么?就是在事务开始和结束时,要么是A=100/B=0的状态要么是A=0/B=100的状态。这跟原子性的概念又有些重合了。但是在有些情况下,比如说事务1执行完A=A-100时,事务2执行了A=A+200,事务2结束,但是事务1回滚了到了A=100/B=0,此时整个数据库少了200,违背了一致性。所以事务如果具备一致性能保证什么?一致性保证一个事务单元全部操作结束了之后才可见,事务开始和结束之间的中间状态不会被其他事务所看到,开始和结束时的状态相同。结合上面来看,在强一致性的保证下,事务与事务之间保持happen-before关系,那么数据库一定是处于一致性的状态。 - 隔离性(Isolation)
书本定义:事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
这个的定义感觉又跟一致性很像,其实在序列化读写这个隔离级别下,就相当于保证了事务的强一致性。但是这样做的代价就是性能很差。
所以隔离性的引入,其实是以性能为理由,对一致性的破坏。核心目的,就是尽可能的提高并行度。 - 持久性(Durability)
每一次的事务提交后就会保证不会丢失。这个没什么好说的。
### 事务的隔离级别
时间: 2024-09-30 12:11:18