写点什么

带你厘清事务一致性(上篇)

用户头像
小舰
关注
发布于: 2021 年 04 月 07 日

前言

事务是数据库中最难搞的概念之一,而事务的一致性问题又是事务研究的核心问题。这篇文章从数据库比较难搞的“事务”着手,分析为什么要有事务,事务有哪些特性以及如何保证事务的这些特性。

单机事务及其一致性

首先这里先限定为单机数据库,事务是数据库操作执行的单位,如果我们提交一个 SQL 命令,那么每个查询或者数据库更新语句就是一个事务。如果我们使用嵌入式 SQL 接口,那么事务的范围就可以通过编程来控制,可能包含一条或者多条 SQL 语句。

1 事务的特性

如果一个数据库声称自己支持事务,那么他必须满足四个特性:A(原子性)C(一致性)I(隔离性)D(持久性)。

原子性:原子性就是指一个事务的执行要么全部成功,要么全部失败,全部失败的意思是指即使有大部分成功了,只要有一小部分失败就要全部失败回滚。

一致性:一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,这听起来很抽象,大部分的解释都是拿一个银行转账的例子来进行说明:比如小舰和小花各有 500 块钱,加起来是 1000 块钱;小舰给小花转了 50 之后,小舰变成了 450,小花变成了 550,他们加起来的总和还是 1000 块钱,如果出现小舰的账户减了 50,小花的账户没有变化,那就出现了不一致的问题了。

隔离性:隔离性是指多个用户并发访问数据库的时候,不同用户的事务操作之间不能互相影响,要保持互相独立性,不然可能就会出现我改了你的,你改了他的,他读了我的,可以想象这种情况下,大家修改和读取到的数据还靠谱么?讲到这里,可能自然而然就会联想到事务的几种隔离级别,没错,事务的隔离级别就是来应对刚刚讲到的【我改了你的,你改了他的,他读了我的】这种混乱的局面,稍后我们详谈。

持久性:持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。那么数据库要通过什么手段来进行这样的保证呢?答案就是日志!对于数据库及各种(大)数据管理系统来讲的重要组成部分,主要的日志有 redu 和 undo 两种,undo 和 redo 在恢复时会撤销所有未提交的事务,重做已提交的事务。

2 如何保证

我们从最简单的开始说起。

持久性:就拿刚刚讲到的持久性开始,上面说到持久性是通过 redu 和 undo 日志来保证的,但是具体是怎么做的呢?

如果某个事务修改一条记录,在进行修改之前,需要将旧值记录到 undo log 中,在进行修改操作后,会将新值写入 redo log 中,在事务修改提交之后,会将提交状态写入 undo log 和 redo log 中,需要注意的是,commit 状态写入 undo log 是在更新数据落盘之后,commit 状态写入 redo log 是在更新数据落盘之前。这样在进行数据恢复时,对于已经 COMMIT 的事务使用 redo log 进行重做,对于没有 COMMIT 的事务,使用 undo log 进行回滚。

原子性和隔离性:这两个特性其实就是为了让事务能够并发执行,在数据库中是通过并发控制管理器或调度器来保障的。

那么,不同事务之间的并发执行是否要真的做到互不影响呢?其实,在实际的数据库实现过程中,为了兼顾一致性和性能,划分了不同的隔离级别,不同的隔离级别对于隔离性(或者说一致性)有不同的约束。隔离级别越低,可能并发性越好,但是事务之间可能就会互相影响;但是如果隔离级别太高,事务之间隔离了,但是并发性以及性能又下去了。因此,不同的数据库会针对不同的场景和性能要求权衡之后采用适当的隔离级别。

数据库事务的隔离级别有 4 种,由低到高分别为 Read uncommitted、Read committed、Repeatable read、Serializable。这四种不同的隔离级别对应着在事务的并发操作中可能会出现的四种不同的不一致性问题:脏读,不可重复读,幻读。

一致性:一致性放在最后是由原因的,一致性是指数据处于一种语义上的有意义且正确的状态。一致性是对数据可见性的约束,正如上面提到的,不同的隔离级别可能会出现不同的一致性问题,因此不同系统或场景对一致性的要求也是不一样的。当然,在数据库事务的 ACID 中,一致性指的是强一致性,但是在分布式的 CAP 理论中,这个一致性可能还包括弱一致性、最终一致性等类型。

3.小结

总结来说,一致性其实是与持久性、原子性和隔离性都有关系的,通过原子性保证事务要么全部执行成功、要么全部执行失败,这其实是一致性的一个根本保证,通过隔离级别保证并发事务之间的数据可见性,从而划分了不同级别的一致性,也可以说隔离级别破坏了一致性,因此在数据库系统实现的时候要在它们之间当然要做一个权衡,持久化存储当然是一致性的最终保障措施,当故障发生的时候,通过日志进行回滚或重做,保证操作结果不丢失。到这里,大家应该对单机事务一致性有了较为充分地了解了,下一节,我将向大家介绍分布式事务的一致性。

发布于: 2021 年 04 月 07 日阅读数: 17
用户头像

小舰

关注

公众号:DLab数据实验室 2020.11.12 加入

中国人民大学硕士

评论

发布
暂无评论
带你厘清事务一致性(上篇)