10事务与并发控制

一、事务的概念

1.事务的特性

事务是用户定义的一个数据库的操作序列,这些操作要么全做,要么不做,是一个不可分割的工作单元。

事务是并发控制与调度的基本单位,也是数据库恢复的基本单位。

事务的特点(ACID特性)

原子性:事务是数据库的逻辑工作单元,事务的所有操作要么都全部成功地执行,要么一个也不被执行。
一致性:事务隔离执行时要保持数据库的一致性;也就是说,事务的执行的结果必须使数据库从一个一致性状态转变到另一个一致性状态,但事务内部无须保证一致性。
隔离性:一个事务的执行不能被其他事务干扰。也就是说,即使多个事务并发执行,任何事务的更新操作直到其成功提交,对其他事务都是不可见的。
永久性:一个事务完成后,它对数据库的改变必须是永久的,即使系统出现故障,它对数据库的更新也将永久有效

破坏事务ACID特性的因素包括:
(1)多个事务并行运行;
(2)事务在运行过程中被强行停止

2.事务状态

在无任何故障情况下,事务能够成功完成,成功完成的事务称为已提交事务
但是,事务并非总能顺利完成,这种事务被称为中止事务
事务必须处于以下状态之一:
(1)活跃状态:初始状态,事务执行时处于该状态
(2)部分提交状态:最后一条语句被执行后的状态
(3)失败状态:发现正常的执行不能继续后的状态
(4)中止状态:事务回滚,并且数据库已被恢复到事务开始执行前的状态
(5)提交状态:成功完成后的状态
在这里插入图片描述
对于被中止的事务,系统有两种选择:
(1)重启事务:仅当引起事务中止的错误不是由事务的内部逻辑所产生时,才有可以重新启动该事务,重启的事务将被看成一个新事务。
(2)杀死事务:如果导致事务中止的错误是事务的内部逻辑错误,如零做除数、程序有误,或者输入错误,或者程序所需数据在数据库中没有找到等情况下,则要杀死该事务。

3.SQL对事务的支持

COMMIT [WORK]:提交当前事务并开始一个新的事务
ROLLBACK [WORK]:中止当前事务

SET TRANSACTION语句可用于设置事务的特性,该语句只有当程序中无事务在执行时才能执行,具体语句形式如下:
SET TRANSACTION <事务模式列表>
<事务模式列表>可以指定存取模式或隔离级别,或两者都指定;
存取模式可以是:READ ONLY只读; READ WRITE读写
隔离级别的格式为
ISOLATION LEVEL <级别>

在这里插入图片描述

二、并发控制概述

1.事务的并发执行

事务的两种执行方式:
(1)串行执行:事务一个接一个的执行。
特点:串行执行的处理比较简单,但是系统利用率不高
(2)并发执行:包括交叉串行执行和同时并发执行
特点:并发可以提高系统效率,但可能破坏事务的ACID性质,导致数据的不一致性

并发执行的好处

①提高吞吐量和资源的利用率
多个事务的并行执行时,一个事务在一个磁盘上进行读写,另一个事务可在CPU上运行,同时第三个事务又可在另一磁盘上进行读写。从而系统的吞吐量增加,即给定时间内执行的事务数量增加,因而也提高了处理器与磁盘利用率
②减少等待时间
系统中可能存在各种各样的事务,有些时间较短,有些较长,如果事务串行执行,短事务可能要等待它前面的长事务完成;并发执行也可以减少平均响应时间(average response time),即一个事务从开始到完成所需要的平均时间

2.并发执行可能导致的问题

(1)丢失修改
(2)读脏数据
(3)不可重复读

三、封锁

在这里插入图片描述
封锁:所谓封锁就是事务T在对某个数据对象操作之前,先向系统发出加锁请求,加锁后事务T就对该数据对象有了一定的控制权,在事务T释放它的锁之前,其它事务不能更新该数据对象

1.共享锁和排他锁

(1)共享锁S:又称读锁。如果事务T获得了数据对象Q上的共享锁,则T可以读但不能写Q,并且在T释放Q上的S锁之前,其它事务只能获得Q上的S锁,而不能获得Q上的X锁
(2)排他锁X:又称写锁。如果事务T获得了数据项Q上的排它锁,则T既可以读又可以写Q,但是在T释放Q上的X锁之前,其它事务既不能获得Q上的S锁,也不能获得Q上的X锁

2.封锁协议

  • 一级封锁协议

事务T在更新数据对象Q之前必须先对其加X锁,直到事务结束才释放;一级封锁协议可防止丢失修改
在一级封锁协议中,如果仅仅是读数据而不对其进行修改,则不需要加锁,因此它不能保证不读“脏”数据和可重复读

  • 二级封锁协议

在一级封锁协议的基础上,进一步要求事务T在读取数据对象Q之前必须先对其加S锁,但是读完后可以立即释放S锁 ;二级封锁协议可以进一步防止读“脏”数据,但不能保证可以重复读

  • 三级封锁协议
    一级封锁协议的基础上,进一步要求事务T在读取数据对象Q之前必须先对其加S锁,并且直到事务结束才能释放S锁;三级封锁协议可以进一步保证可重复读,可以很好地避免并发导致的问题

3.活锁与死锁

活锁: 活锁又称饥饿,是某个事务因等待锁而处于无限期等待状态

活锁的解决办法:

可以采用先来先服务的策略来避免某个事务无限期等待
即当多个事务请求封锁同一数据对象时,封锁子系统按请求封锁的先后次序对事务排队
数据对象上的锁一旦释放,就将锁授予申请队列中的第一个事务

死锁:死锁是两个或两个以上的事务之间的循环等待现象

死锁的预防:

一次封锁法: 每个事务必须一次将所有要使用的数据全部加锁后,再实际执行事务操作,否则事务不进行任何实际行动也不封锁任何数据
顺序封锁法 :预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁

一次封锁法存在的问题:

(1)降低系统的并发度:一次封锁事务全部要用的数据,将导致更多并发事务的等待
(2)事先确定事务要封锁的数据对象困难:数据库中并发的事务在执行过程中可能会改变封锁对象,所以很难事先一次性精确确定要封锁的数据对象,解决的办法就是扩大封锁范围,从而进一步降低了并发度,导致系统总体资源利用率的下降

顺序封锁法存在的问题:

维护资源的封锁顺序是非常困难的:由于数据库中要封锁的数据对象极多,并且随数据的插入、删除等操作而不断变化

4.死锁的检测与解除

死锁的检测:

超时法 超时法的优点是实现简单。但是,若时限限定太小,则对于运行时间长的事务可能误判;若时限限定太长,则死锁发生后不能及时发现

等待图法:
事务等待图是一个有向图G=(T,U),其中,T为结点的集合,每个结点表示正运行的事务;U为边的集合,每条边表示事务等待的情况,若T1等待T2,说明T1申请对T2已经封锁的数据对象进行加锁而处于等待状态,则T1、 T2之间划一条有向边,从T1指向T2 ;
系统发生死锁,当且仅当事务等待图中存在环(回路)。回路中的事务都处于死锁状态

解除死锁:

解除死锁的基本方法是
选择一个或多个处于死锁状态的事务,将其撤销并释放这些事务持有的所有的锁,从而打破了循环等待条件,解除死锁,使得其他事务能够继续运行。当然,被撤消的事务对数据库的更新必须恢复(回滚),并且要在稍后需要重新运行

四、并发调度的可串行化

1.串行调度与并发调度

串行调度: 所谓一组事务的串行调度是指这些事务一个接一个地执行,其中每个事务都在上一个事务(如果有的话)完全结束之后才开始执行。

串行调度总是正确的
对于n个事务,存在n!个不同的串行调度,可能导致不同的结果

并发调度
两个事务并发,执行顺序可能有多种
对于并发调度,n个事务的事务组,可能调度的总数要远大于n!
并发调度正确性准则

一组事务的一个并发调度S是正确的,当且仅当调度S的执行结果与某一个串行调度的执行结果相同。此时,我们称并发调度S是可串行化的
理由: 任何串行调度都不破坏数据的一致性,都是正确的。如果一个并行调度的结果与某个串行调度的结果相同,则它也不会破坏数据的一致性,因而我们没有理由认为它不正确

冲突等价
反复交换S中隶属于两个不同事务的非冲突指令所得到的调度S’与S等价,称作冲突等价(conflict equivalent)
冲突可串行化
给定一个调度S,反复交换S中隶属于不同事务的非冲突操作,将隶属于同一事务的操作移动到一起。如果能够得到一个串行调度,则S是冲突可串行化的,否则不是

2.视图可串行化

视图可串行化是一种限制比较宽松的调度等价形式,同样是基于事务的读写操作

视图等价
设S1和S2是同一组事务的两个调度。调度S1和S2是视图等价的(view equivalent),如果它们满足以下三个条件:

(1) 对于每个数据项Q,若事务Ti在调度S1中读取了Q的初始值,那么在调度S2中Ti也读取Q的初始值
(2)对于每个数据项Q,若事务Ti在调度中执行了read(Q)并且读取的值是由事务Tj执行write(Q)产生的,则在调度S2中, Ti的read(Q)操作读取的值Q也必须是由同一个write(Q)产生的
(3)对于每个数据项Q,若事务Ti在调度S1中有执行了最后的write(Q)操作,则在调度S2中该事务也必须执行最后的write(Q)操作

视图可串行化
如果调度S视图等价于一个串行调度,则称调度S是视图可串行化的

每个冲突可串行化的调度都是视图可串行化的。但是,存在视图可串行化的调度,它不是冲突可串行化的

五、两阶段封锁

两阶段锁协议要求每个事务:
在对任何数据进行读、写操作之前,首先要申请并获得对该数据对象的相应封锁
在释放一个锁之后,事务不能再申请任何其他锁

两阶段锁协议对比一次封锁法
两阶段封锁协议并不要求事务一次将所有要使用的数据对象全部加锁
遵守两阶段锁协议的事务仍然可能发生死锁
遵守一次封锁法不会发生死锁

为了避免级联回滚,产生了两种改进的两阶段封锁协议:
严格两阶段封锁协议:除满足两阶段锁协议的要求外,该协议进一步要求事务持有的排它锁必须在该事务提交或者中止后才能释放
强两阶段封锁协议:除满足两阶段锁协议的要求外,该协议进一步要求事务所持有的所有的锁必须保持到事务提交或中止

六、多粒度封锁

前面讲述的并发控制机制主要是将数据项作为同步单元
但是在有些情况下,系统需要将多个数据项聚为一组作为一个同步单元,甚至于将整个数据库作为一个封锁对象。这种封锁对象的大小就称为粒度

系统能够同时支持多种封锁粒度供不同的事务选择的封锁方法称之为多粒度封锁

选择封锁粒度时应该同时考虑封锁开销和并发度两个因素
封锁的粒度越大,数据库所能封锁的数据单元就越少,并发度就越小,系统开销就越小;
封锁的粒度越小,并发度就高,系统开销就越大

1.粒度的层次结构

两种形式被封锁:
显式封锁:是直接加到数据对象上的封锁
隐式封锁:是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁
显式封锁和隐式封锁的效果是一样的

几种常用的意向锁:
IS锁:意向共享锁(Intent Share Lock)
如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。
IX锁:意向排它锁(Intent Exclusive Lock)
如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。
SIX锁: 共享意向排它锁(Share Intent Exclusive
Lock) 如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX
引进SIX锁的直接动机之一是,许多事务都需要读一个关系的全部或大部分元组,并且修改其中少量元组。这种事务需要对整个关系加S锁,并且可能要对关系的某些元组加X锁

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全糖去冰不加料

打赏一块钱💰也是钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值