数据库——事务与并发控制

版权声明:原创作品转载需标明作者与地址 https://blog.csdn.net/zjuwxx/article/details/90346903

目录

一、事务概述

1.1定义

1.2特性

二、并发控制概述

2.1事务的并发执行

2.2并发执行导致的问题

2.2.1丢失修改

2.2.2读“脏”数据

2.2.3不可重复读

三、封锁

3.1基本锁类型

3.2封锁协议

3.2.1一级封锁协议

3.2.2二级封锁协议

3.2.3三级封锁协议

3.3活锁与死锁

3.3.1活锁

3.3.2死锁

3.3.3死锁的检测与解除

四、并发调度的可串行化

4.1串行调度与并发调度

4.1.1串行调度

4.1.2并发调度

4.2冲突可串行化

五、两阶段锁协议

六、多封锁粒度

6.1粒度

6.2意向锁


一、事务概述

1.1定义

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

事务是并发控制的基本单位,是数据库恢复的基本单位,是数据库的逻辑基本逻辑单元

数据库恢复机制和并发控制机制是数据库管理系统的重要组成部分

在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序

--显式定义事务
begin transaction 
SQL 语句1 
……  ……
commit / rollback

/*
commit
    事务正常结束
    提交事务的所有操作(读+更新)
    事务中所有对数据库的更新写回到磁盘上的物理数据库中

rollback
    事务异常终止
    事务运行的过程中发生了故障,不能继续执行
    系统将事务中对数据库的所有已完成的操作全部撤销
    事务滚回到开始时的状态
*/
--将数学课程号由2修改为22
/*
解析:
所涉及的关系:Course和SC,根据参照完整性约束,应将两表中的2都改为22。要将修改两个表的两个SQL语句定义成一个事务。因为DBMS对这两个语句要么都执行,要不都不执行
*/

begin transaction
    update Course set CNO='22' where CNO='2'
    update SC set CNO='2' where CNO='22'
commit

1.2特性

原子性 

  • 事务是数据库的逻辑工作单元
  • 事务的所有操作要么都全部成功地执行,要么都不执行
  • 若事务因故障而中止,则要设法消除该事务所产生的影响,使数据库恢复到该事务执行前的状态

一致性

  • 事务执行的结果必须使数据库从一个一致性状态转变到另一个一致性状态

隔离性 

  • 一个事务的执行不能被其他事务干扰。多个事务并发执行,任何事物的更新操作直到其成功提交,对其他事务都是不可见的

持久性 

  • 一个事务完成后,它对数据库的改变必须是永久的,即使系统出现故障,它对数据库的更新也将永久有效

二、并发控制概述

事务的并发执行是数据库系统提高系统效率的有效方法,但可能破坏事务的 ACID性质,导致数据的不一致性

2.1事务的并发执行

1、并发执行的理由

  • 提高吞吐量和资源利用率
  • 减少等待时间

2、并发执行方式

  • 交叉并发方式
  1. 单机系统中,事务的并行操作轮流交叉运行
  2. 优点:能够减少处理机的空闲时间,提高系统的效率
  3. 缺点:不是真正的并发操作,可能会产生数据不一致
  • 同时并发方式
  1. 多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事务,实现多个事务真正的并行运行
  2. 优点:最理想的并发方式
  3. 缺点:受制于硬件环境,同样可能会产生数据不一致

2.2并发执行导致的问题

2.2.1丢失修改

2.2.2读“脏”数据

2.2.3不可重复读

产生原因

  • 事务T1读取某一数据后,事务T2对其做了修改,事务T1再次读取该数据时,发现与前次不同
  • 事务T1按一定条件读取了某些数据记录后,事务T2删除了其中的部分记录,事务T1再次按相同条件读取记录时,发现有些记录不存在
  • 事务T1按一定条件读取了某些数据记录后,事务T2插入了一些记录,事务T1再次按相同条件读取记录时,发现多了一些记录

例:飞机订票系统中的一个活动序列

①甲售票点(事务T1)读出某航班的机票余额A,设A=16;

②乙售票点(事务T2)读出同一航班的机票余额A,也为16;

③甲售票点卖出一张机票,修改余额A←A-1,所以A为15,把A写回数据库;

④乙售票点也卖出一张机票,修改余额A←A-1,所以A为15,把A写回数据库

结果明明卖出两张机票,数据库中机票余额只减少1

这种情况称为数据库的不一致性,是由并发操作引起的

在并发操作情况下,对T1、T2两个事务的操作序列的调度是随机的。若按上面的调度序列执行,T1事务的修改就被丢失。原因:第4步中T2事务修改A并写回后覆盖了T1事务的修改

产生上述三类不一致性的主要原因就是并发操作破坏了事务的隔离性。并发控制就是要用正确的方式调度并发操作,使某个事务的执行不受其它事务的干扰

并发控制的主要技术:封锁、时间戳、乐观控制法、多版本并发控制

三、封锁

封锁即事务在对某个数据对象操作之前,先向系统发出加锁请求,加锁后事务对该数据对象有了一定的控制权,在事务释放它的锁之前,其他事务不能更新该数据对象

3.1基本锁类型

排它锁又称写锁或X,若事务 T对数据对象 A加上X锁,则只允许 T读取和修改 A,任何其它事务都不能再对 A读取和修改,直到 T释放A上的锁

共享锁又称读锁或S,若事务 T对数据对象 A加上 S锁,则事务 T可以读 A但不能修改 A,其它事务只能再对 A读取,而不能修改,直到 T释放 A上的锁2.2封锁协议

3.2封锁协议

3.2.1一级封锁协议

事务T在修改数据对象R之前必须先对其加X锁,直到事务结束才释放

作用:一级封锁协议可防止丢失修改,并保证事务T是可恢复的

说明:在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读“脏”数据

3.2.2二级封锁协议

在一级封锁协议的基础上,事务T在读取数据对象R之前必须先对其加S锁,但是读完后即可释放S锁

作用:二级封锁协议可以防止丢失修改和读“脏”数据

说明:在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读

3.2.3三级封锁协议

在一级封锁协议的基础上,事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放

作用:三级封锁协议可防止丢失修改、读脏数据和不可重复读

三级协议的主要区别

  • 什么操作需要申请封锁以及何时释放锁(即持锁时间)
  • 封锁协议级别越高,一致性程度越高

 

X

S

一致性保证

 

操作结束释放

事务结束释放

操作结束释放

事务结束释放

不丢失

修改

不读“脏”数据

可重复

一级封锁协议

 

 

 

 

 

二级封锁协议

 

 

 

三级封锁协议

 

 

3.3活锁与死锁

3.3.1活锁

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

避免活锁:先来先服务,当多个事务请求封锁同一数据对象时,按请求封锁的先后次序对这些事务排队,该数据对象上的锁一旦释放,首先批准申请队列中第一个事务获得锁

3.3.2死锁

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

死锁的预防

1、一次性封锁法

每个事务必须一次将所有要使用的数据对象全部加锁后,在实际执行实务操作,否则事务不进行任何实际行动也不封锁任何数据

存在问题

  • 使数据的上锁时间增长,降低系统的并发度
  • 事先确定事务要封锁的数据对象很难

2、顺序封锁法

预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁

存在的问题

  • 维护成本很高,数据库系统中封锁的数据对象极多,并且随数据的插入、删除等操作而不断地变化,要维护这样的资源的封锁顺序非常困难

上述两种方法虽然都可以有效地预防死锁,但都存在一些问题,因此真正实施起来并不方便。所以预防死锁的策略不很适合数据库的特点,DBMS普遍采用诊断死锁并解除的方法

3.3.3死锁的检测与解除

1、死锁的检测

数据库系统通常采用超时或事务等待图法发现死锁

2、解除死锁

选择一个或多个处于死锁状态的事务,将其撤消并释放这些事务持有的所有的锁,从而打破了循环等待条件,解除死锁,使其它事务能够继续运行

四、并发调度的可串行化

4.1串行调度与并发调度

4.1.1串行调度

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

对于一组事务,串行调度总是正确的

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

4.1.2并发调度

一组事物的并发调度是指这些事务中至少有两个事务都开始了它们的执行,并且都尚未结束

并发调度正确性规则:一组事物的并发调度是正确的,当且仅当调度的执行结果与某一个串行调度的执行结果相同,此时称并发调度是可串行化的

4.2冲突可串行化

冲突操作:是指不同的事务对同一数据的读写操作和写写操作

     Ri(x)与Wj(x)         /*事务Ti读x,Tj写x,其中i≠j*/

     Wi(x)与Wj(x)         /*事务Ti写x,Tj写x,其中i≠j*/

不能交换的动作包括一事务的两个操作不同事务的冲突操作

一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc',如果Sc'是串行的,称调度Sc是冲突可串行化的调度若一个调度是冲突可串行化,则一定是可串行化的调度

冲突可串行化调度是可串行化调度的充分条件,不是必要条件

五、两阶段锁协议

“两阶段”锁的含义是事务分为两个阶段

第一阶段是获得封锁,也称为扩展阶段

  • 事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁

第二阶段是释放封锁,也称为收缩阶段

  • 事务可以释放任何数据项上的任何类型的锁,但是不能再申请任何锁

两阶段锁协议的正确性

  • 若所有事务都遵守两段封锁协议,则对这些事务的任何并发调度策略都是可串行化的
  • 两阶段锁协议是并发控制正确性的充分条件,但不是必要条件。即若所有事务都遵守两阶段锁协议,则这些事务的任何并发调度都是可串行化的,反之,一个并发调度是可串行化的,不一定所有事务都遵守两阶段锁协议

两段锁协议与防止死锁的一次封锁法

  • 一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议
  • 但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁

六、多封锁粒度

6.1粒度

封锁对象的大小称为粒度,可以是数据库、表、记录、字段等

封锁粒度与系统的并发度和并发控制的开销密切相关。封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;封锁的粒度越小,并发度越高,但系统开销也就越大


多粒度封锁是同时支持多种封锁粒度供不同事务选择的封锁方法

  • 依赖的数据结构——多粒度树
  1. 将数据库中的数据对象按相互关系和粒度大小组织成的树型结构,其中根结点表示最大数据粒度,通常为整个数据库,叶结点表示最小数据粒度

多粒度封锁协议允许对多粒度树中的每个结点独立地加锁,并且对每一个结点加锁隐含着对其后裔结点也加以同样的锁

  • 在多粒度封锁中一个数据对象可能以两种方式封锁:显式封锁隐式封锁
  1. 由事务直接加到数据对象上的封锁称为显式封锁
  2. 因上级结点加锁而引起下级对象被封锁,称为隐式封锁
  3. 显式封锁和隐式封锁的效果是一样

系统检查封锁冲突时要检查显式封锁还要检查隐式封锁

多粒度封锁方法

为对某数据对象加锁,系统要检查

  • 该对象有无显式封锁与之冲突
  • 该对象的上级结点有无显式封锁与之冲突
  • 该对象的下级结点有无显式封锁与之冲突

当无任何冲突时方能加锁成功

6.2意向锁

对任一结点加锁时,必须先对其上级结点加意向锁

目的:提高对某个数据对象加锁时系统的检查效率

作用:减少加锁时的封锁冲突检查工作量。只需检查上级结点与本结点是否已加了不相容的锁,并通过本结点的意向锁了解下级结点是否有不相容的锁,从而不必再检查下级结点

三种意向锁

  • 意向共享锁(IS锁):如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁
  • IX锁:如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁
  • SIX锁:如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX

锁的强度 指它对其他锁的排斥程度,一个事务在申请封锁时以强锁代替弱锁是安全的,反之则不然

意向锁的封锁和释放顺序

  • 申请封锁时应该按自上而下的次序进行
  • 释放封锁时则应该按自下而上的次序进行

猜你喜欢

转载自blog.csdn.net/zjuwxx/article/details/90346903