数据库系统概念(机械工业出版社,第六版)复习——第十二章:事务管理

第十二章 事务管理

 

事务定义

事务是访问并可能更新各种数据项的一个程序执行单元。

这些操作要么都做,要么都不做,是一个不可分割的工作单位。例如银行转账

SQL中事务的定义

       Commitwork表示提交,事务正常结束。

       Rollbackwork表示事务非正常结束,撤消事务已完成的操作,回滚到事务开始时状态。

Read(X) and write(X)

read(X):从数据库传送数据项X到事务的工作区中

write(X):从事务的工作区中将数据项X写回数据库

事物特性(ACID)

原子性(Atomicity)

       事务中包含的所有操作要么全做,要么全不做。原子性由恢复系统实现。

一致性(Consistency)

       事务的隔离执行必须保证数据库的一致性。事务开始前,数据库处于一致性的状态;事务结束后,数据库必须仍处于一致性状态;事务的执行过程中可以暂时的不一致。数据库的一致性状态由用户来负责,由并发控制系统实现。

如银行转账,转账前后两个帐户金额之和应保持不变。

隔离性(Isolation)

       系统必须保证事务不受其它并发执行事务的影响。对任何一对事务T1,T2,在T1看来,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。隔离性通过并发控制系统实现。

持久性(Durability)

       一个事务一旦提交之后,它对数据库的影响必须是永久的。系统发生故障不能改变事务的持久性。持久性通过恢复系统实现。

事务状态图

并行VS串行

基本比较:

并行事务会破坏数据库的一致性,串行事务效率低。

并行的优点:

一个事务由不同的步骤组成,所涉及的系统资源也不同。这些步骤可以并发执行,以提高系统的吞吐量(throughput)

系统中存在着周期不等的各种事务,串行会导致难于预测的延迟。如果各个事务所涉及的是数据库的不同部分,采用并行会减少平均响应时间(average response time)

核心问题:

       在保证一致性的前提下最大限度地提高并发度。

并发操作带来的数据不一致性

丢失修改(lost update)

不可重复读(non-repeatable read)

读“脏”数据(dirty read)

丢失数据

事务1与事务2从数据库中读入同一数据并修改,事务2的提交结果破坏了事务1提交的结果,导致事务1的修改被丢失。

不可重复读

事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果。

三类不可重复读:

事务1读取某一数据后:

1.事务2对其做了修改,当事务1再次读该数据时,得到与前一次不同的值。

2.事务2删除了其中部分记录,当事务1再次读取数据时,发现某些记录神秘地消失了。

3.事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录。

后两种不可重复读有时也称为幻影现象(phantomrow)。

读“脏”数据

事务1修改某一数据,并将其写回磁盘,事务2读取同一数据后,事务1由于某种原因被撤消,这时事务1已修改过的数据恢复原值,事务2读到的数据就与数据库中的数据不一致,是不正确的数据,又称为“脏”数据。

事务调度

事务的执行顺序称为一个调度(schedule),表示事务的指令在系统中执行的时间顺序。

当并行调度等价于某个串行调度时,则称它是正确的。

冲突可串行化

冲突指令:

当两条指令是不同事务相同数据项上的操作,并且其中至少有一个是write指令时,则称这两条指令是冲突的。

冲突等价:

       如果调度S可以经过一系列非冲突指令交换转换成调度S',则称调度S与S'是冲突等价的(conflictequivalent)。

冲突可串行化:

       当一个调度S与一个串行调度冲突等价时,则称该调度S是冲突可串行化的(conflict serializable)。

冲突可串行化判定:优先图。

可恢复调度(Recoverable Schedule)

事务的恢复:

一个事务失败了,应该能够撤消该事务对数据库的影响。如果有其它事务读取了失败事务写入的数据,则该事务也应该撤消。

可恢复调度:

对于每对事务T1与T2,如果T2读取了T1所写的数据,则T1必须先于T2提交。

无级联调度

级联调度:

由于一个事务故障而导致一系列事务回滚。

无级联调度:

对于每对事务T1与T2,如果T2读取了T1所写的数据,则T1必须在T2读取之前提交。

<注>无级联调度必是可恢复调度

事务隔离性

按照隔离级别从低到高的顺序:

未提交读:允许读取未提交数据。(当事务A更新某条数据时,不容许其他事务来更新该数据,但可以读取。)

已提交读:只允许读取已提交数据,但不要求可重复读。(当事务A更新某条数据时,不容许其他事务进行任何操作包括读取,但事务A读取时,其他事务可以进行读取、更新。)

可重复读:只允许读取已提交数据,而且一个事务两次读取一个数据项期间,其他事务不得更新该数据,但是该事务不要求与其他事务可串行化。

可串行化:保证可串行化调度。

隔离级别

肮脏读取

不可重复读取

幻象读取

未授权读取

可能发生

可能发生

可能发生

授权读取

-

可能发生

可能发生

可重复读取

-

-

可能发生

可序列化

-

-

-

并发机制

并发控制机制的任务:对并发操作进行正确调度、保证事务的隔离性、保证数据库的一致性。

基本封锁类型:

排它锁(exclusive lock,简记为X锁)

共享锁(Share lock,简记为S锁)

共享锁

共享锁又称为读锁。若事务T对数据对象Q加上S锁,事务T可读但不能写Q,其它事务只能再对Q加S锁,而不能加X锁,直到T释放Q上的S锁。

排它锁

排它锁又称为写锁。若事务T对数据对象Q加上X锁,则事务T既可以读又可以写Q,其它任何事务都不能再对Q加任何类型的锁,直到T释放A上的锁。

死锁

活锁(饿死)

饥饿/饿死:

不断出现的申请并获得S锁的事务,使申请X锁的事务一直处在等待状态。

饥饿的防止:

对申请S锁的事务,如果有先于该事务且等待的加X锁的事务,令申请S锁的事务等待。

保证可串行性的封锁协议(两阶段封锁协议)

定义:每个事务分两个阶段提出加锁和解锁申请。

增长阶段(growing phase):事务可以获得锁,但不能释放锁。

缩减阶段(shrinking phase):事务可以释放锁,但不能获得新锁。

封锁点(lock point):事务最后加锁的位置,称为事务的封锁点, 记作Lp(T)。

并行执行的所有事务均遵守两段锁协议,则对这些事务的所有并行调度策略都是可串行化的。所有遵守两段锁协议的事务,其并行执行的结果一定是正确的。

事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件。可串行化的调度中,不一定所有事务都必须符合两段锁协议。

两阶段封锁协议不保证不会发生死锁。

严格两阶段封锁协议:除了要求封锁是两阶段之外,还要求事务持有的所有排他锁必须在事务结束后,方可释放。

强两阶段封锁协议:事务提交之前,不得释放任何锁。在强两阶段封锁协议下,事务可以按其结束的顺序串行化。

锁转换

Upgrade:从共享锁提升为排他锁

Downgrade:从排他锁降级为共享锁

锁升级只能发生在增长阶段,锁降级只能发生在缩减阶段。

多粒度封锁的必要性

事务访问数据的粒度不同

DB、Table、Tuple、…

单一封锁粒度的问题

封锁粒度大:并发性低

封锁粒度小:访问大粒度数据加锁量巨大

多粒度封锁

根据访问数据的粒度,确定封锁的粒度

以求加锁量有限,并可获得最大的并发性

多粒度封锁的基本原则

大粒度数据由小粒度数据组成;

允许对不同粒度数据进行封锁;

事务对大粒度数据加锁,隐含地对组成大粒度数据的所有小粒度数据加锁。

多粒度层次结构

多粒度层次树,子节点表示的数据是父节点表示数据的一部分。

意向锁(intention lock mode)

如果一个节点加上了意向锁,则意味着要在树的较低层进行显示加锁。

在一个节点显式加锁之前,该结点的全部祖先均加上了意向锁。

事务判定是否能够成功地给一个结点加锁时,不必搜索整棵树。

多粒度封锁相容矩阵

共享意向锁(IS)/排他意向锁(IX)/共享排他意向锁(SIX)

多粒度封锁协议

遵从锁的相容矩阵;

根结点必须首先加锁,可以加任何类型的锁;

仅当Ti对Q的父结点持有IX或IS锁时,Ti对于结点Q加S或者Is锁;

仅当Ti对Q的父结点持有IX或SIX锁时, Ti对于结点Q加X、SIX、IX锁;

仅当Ti未曾对任何结点解锁时,Ti可以对结点加锁(两阶段的);

仅当Ti当前不持有Q的子节点的锁时,Ti可以对节点Q解锁。

特点:

增加了并发行,减少了锁开销。

适应范围:

只存取几个数据项的短事务,

由整个文件或一组文件形成报表的长事务。

基于时间戳的协议

时间戳排序协议的目标:

令调度冲突等价于按照事务开始早晚次序排序的串行调度。

时间戳排序协议的基本思想:

开始早的事务不能读开始晚的事务写的数据;

开始早的事务不能写开始晚的事务已经读过或写过的数据。

数据项时间戳

W-timestamp(Q):表示成功执行write(Q)的所有事务的最大的时间戳。

R-timestamp(Q):表示成功执行read(Q)的所有事务的最大的时间戳。

注意:不是最后执行Read(Q)的事务的时间戳

例如:TS(T1)=1;TS(T2)=2;

               T2:read(Q)  //r-ts(Q)=2

               T1:read(Q)  //r-ts(Q)=2  (≠1!)

时间戳排序协议性质和特点

保证冲突可串行化;

冲突可串行化的调度不一定能被时间戳排序协议调度出来;

无死锁;

存在饥饿/饿死现象(事务可能被反复回滚、重启);

不能保证可恢复性(可以扩展协议以保证可恢复性,如跟踪提交依赖等)。

Tomas写规则

基于有效性检查的协议

每个事务Ti在其生存期中按两个或三个阶段执行:

1、读阶段:各数据项值被读入,并保存在事物Ti的局部变量中。

2、有效性检查阶段:判断是否可以将write操作所更新的临时局部变量值复制到数据库而不违反可串行性。

3、写阶段:若事务Ti已经通过有效性检查,进行实际的数据库更新,否则,回滚。

为了进行有效性检测测试,需要知道事务Ti的各个阶段何时进行,设立三个时间戳:

1、Start(Ti):事务Ti开始执行的时间。

2、Validation(Ti):事务Ti完成读阶段并开始其有效性检查阶段的时间。

3、Finish(Ti):事务Ti完成写阶段的时间。

数据恢复

基于日志的恢复

 

你可能感兴趣的:(数据库)