数据库系统概念笔记——第十四章:事务
Posted 叶卡捷琳堡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库系统概念笔记——第十四章:事务相关的知识,希望对你有一定的参考价值。
文章目录
第十四章:事务
14.1 事务概念
事务是访问并更新可能各种数据项的一个程序执行单元。
事务的ACID特性
- 原子性:事务的所有操作在数据库中要么全部正确反映出来,要么完全不反映
- 一致性:隔离执行事务时(在没有其它事务并发执行的情况下),保持数据库的一致性
- 隔离性:尽管多个事务可能并发执行,但系统保证,对于任何一对事务Ti和Tj,在Ti看来,Tj在Ti执行之前已经完成执行或在Ti执行之后完成执行。因此每个事务都感受不到系统中有其它事务并发执行
- 持久性:一个事务成功完成后,和他对数据库的改变必须是永久的,即使出现系统故障
14.2 一个简单的事务模型
银行转账的例子:从账户A过户$50到账户B的事务
事务运用以下两个操作访问数据
- read(X):从数据库把数据项X传送到执行read操作的事务的主存缓冲区的一个也被称为X的变量中
- write(X):从执行write的事务的主存缓冲区的变量X中把数据项X传回数据库中
实际上write操作不一定立即更新磁盘上的数据,write操作的结果可以临时存储在某处,以后再写到磁盘上
这个事务可以表示为:
14.4 事务原子性和持久性
事务并非总能成功地执行完成。这种事务称为中止了。要确保原子性,中止事务必须对数据库的状态不造成影响。一旦中止事务造成的变更被撤销,我们就说事务已回滚
成功完成执行的事务称为已提交
事务必须处于以下状态之一
- 活动的:初始状态,事务执行时处于这个状态
- 部分提交的:最后一条语句执行后
- 失败的:发现正常的执行不能继续后
- 中止的:事务回滚并且数据库已恢复到事务开始执行前的状态后
- 提交的:成功完成后
如果事务是提交的或中止的,它称为已经结束的
14.5 事务隔离性
串行执行:一次执行一个事务,每个事务仅当当前事务执行完后才开始
并发执行可以提高吞吐量和资源利用率,并减少等待时间
在数据库中使用并发执行的动机在本质上与操作系统中使用多道程序的动机是一样的
数据库系统必须控制事务之间的交互,以防止它们破坏数据库的一致性。系统通过并发控制机制保证这一点
假设现在有两个事务,事务T1:从账户A过户50到账户B。事务T2:从账户A将存款余额的10%过户到账户B的事务
对于这两个事务,有多种调度顺序
一组事务的调度必须包含这一组事务的全部指令,并且必须保持指令在各个事务中出现的顺序
当然还有下面这种并发调度
并不是所有并发执行都能得到正确的结果。保证所执行的任何调度都能使数据库处于一致状态,这是数据库系统的任务,数据库系统中负责完成此任务的被称为并发控制部件
在并发执行中,通过保证所执行的任何调度都与没有并发执行的调度效果一样,我们可以确保数据库的一致性。也就是说,调度应该在某种意义上等价于一个串行调度。这种调度称为可串行化调度
并发执行时可能带来的问题
- 丢失修改
- 不可重复读
- 读“脏”数据
14.6 可串行化
只考虑read和write两种操作,关注一种称为冲突可串行化的形式
考虑一个调度S,其中含有分别属于I与J的两条连续指令Ii和Ij,如果I,J引用不同的数据项,则交互I,J不会影响调度中任何指令的结果。但如果I,J引用相同数据项Q,则两者的顺序很重要
考虑以下四种情形
当I与J是不同事务在相同的数据项上的操作,并且其中至少有一个是write指令时,我们说I与J是冲突的
设I与J是调度S的两条连续指令。若I与J是属于不同事务的指令且不冲突,则可以交换I与J的顺序得到一个新的调度S‘,我们说S’与S等价
如果调度S可以经过一系列非冲突指令交换转换成S‘,我们称S与S’是冲突等价的
若一个调度S与一个串行调度等价,则称调度S是冲突可串行化的
判断冲突可串行化的一个方法
构造一个有向图,称为优先图
如果调度S的优先图有环,则调度S是非冲突可串行化的,如果优先图无环,则调度S是冲突可串行化的
14.7 事务隔离性和原子性
14.7.1 可恢复调度
一个可恢复调度应该满足:对于每对事务Ti和Tj,如果Tj读取了之前由Ti所写的数据项,则Ti应先于Tj提交
调度9是不可恢复的,如果要使调度9可恢复,则T7应推迟到T6之后提交
14.8 事务隔离性级别
SQL标准规定的隔离性级别从高到低如下
- 可串行化:保证可串行化调度
- 可重复读:只允许读取已提交数据,而且在一个事务两次读取一个数据项期间,其他事务不得更新该数据。
- 已提交读:只允许读取已提交数据,但不要求可重复读。比如在事务两次读取一个数据项期间,另一个事务更新了该数据并提交
- 未提交读:允许读取未提交数据。
以上所有隔离级别都不允许脏写,即如果一个数据项已经被另外一个尚未提交或中止的事务写入,则不允许对该数据项进行操作
14.9 隔离性级别的实现
可以使用锁和时间戳实现隔离,具体的操作方式下一章里会具体介绍
锁
一个事务可以封锁其访问的数据项,而不用封锁整个数据库。在这种策略下,事务必须在足够长的时间内持有锁来保证可串行化,但是这一周期又要足够短使其不会影响性能
有两种锁,共享锁和排他锁。共享锁用于事务读的数据项,而排他锁用于事务写的数据项。许多事物可以同时持有一个数据项上的共享锁,但是只有当其它事务在一个数据项上不持有任何锁时,一个事务才允许持有该数据项上的排他锁。
时间戳
为每个事务分配一个时间戳,通常在开始的时候分配。对每个数据项,系统维护两个时间戳。数据项的读时间戳记录读该数据项的事务的最近的时间戳。数据项的写时间戳记录写入该数据项当前值的事务的时间戳。
时间戳确保访问冲突的情况下,事务按照事务时间戳的顺序来访问数据项。
以上是关于数据库系统概念笔记——第十四章:事务的主要内容,如果未能解决你的问题,请参考以下文章