Concurrency Control Theory
本节课主要介绍事务的概念和特性。
Definitions
事务是一组数据库操作(比如SQL语句)的集合,进一步可以抽象为对某些数据对象的读写操作序列。因为多个用户请求并发运行时,对数据对象的读写可能产生不一致的现象,所以需要事务及其机制辅助进行管制。
一个数据库中的所有事务需要满足以下几个性质:
- 原子性:事务包含的操作要么全部执行要么全部不执行
- 一致性:如果数据库在事务开始前是一致的,那么在该事务完成后也要确保数据库是一致的;数据库的一致性由用户指定, 比如银行转账时,数据库的一致性体现在两个账户的总额保持不变。
- 隔离性:事务之间是相互隔离的,当有若干事务并发执行时,各事务间不影响,表现出与某种串行执行一样的结果。
- 持久性:事务提交后,对数据库造成的影响应当是持久性的
ACID: Atomicity
通常可以采用两种方法实现事务的原子性:
- Logging:DBMS为事务中已执行的操作记录上日志,并在事务异常终止时进行undo操作。
- Shadow Paging:DBMS为每个事务单独分配pages进行修改,当事务正常提交后再更新进入数据库,如果事务异常终止,则只需要删除其对应的pages即可。这种做法不常用,因为它只在事务异常终止时的恢复阶段较方便,在正常情况下效率低于Logging。
ACID: Consistency
数据库一致性:数据库中的数据需要满足一些现实世界的约束(用户自定义的)以及一些整数约束(如年龄不应该为负数等等)
事务一致性:如果数据库在事务执行前是一致的,那么在事务提交后也应该一致,应用层应该使设计出来的事务满足这个特性
ACID: Isolation
DBMS确保事务间隔离,通过一些机制让正在执行的事务以为当前没有其他事务与自己并行执行。最简单的方式是串行执行事务,但是为了提高效率,当前的系统通常采用事务的并行执行。需要保证的是,并行执行的结果与串行执行的结果一致,从而实现并行隔离性。
并行调度器会产生许多并行执行方案,只有在并行执行方案的执行结果与某种串行执行方案的结果一致时,我们才认为这种执行方案是符合事务隔离性的,或者说这种并行执行方案是可串行化的。
可串行化的方案有两种:
- 冲突可串行化
- 视图可串行化
主要看冲突可串行化,如何判断一个执行方案是冲突可串行化的?
首先冲突是什么?冲突就是两个方案中的Read和Write操作前后冲突了,有以下三种情况:
- Read-Write Conflicts (“Unrepeatable Reads”)
- Write-Read Conflicts (“Dirty Reads”)
- Write-Write Conflict (“Lost Updates”)
然后是,判断执行方案为冲突可串行化方案的方法,可以尝试构造这样一个有向图:顶点为所有事务、边为事务之间的冲突(冲突由两个事务的两个操作组成,边的方向由时间戳小的事务指向时间戳大的事务),如果为DAG,则该执行方案为冲突可串行化的方案。
如下图为冲突可串行化的执行方案:
如下图不是冲突可串行化的执行方案:
ACID: Durability
DBMS需要确保在系统断电时,已提交的事务所造成的影响可持久化,可采用Logging或Shadow Paging的方式,无论采用哪种方法,需要借助非易失性存储实现。