系统文章目录
数据库的四个基本概念:数据、数据库、数据库管理系统和数据库系统
数据库系统的三级模式和二级映射
数据库系统外部的体系结构
数据模型
关系数据库中的关系操作
SQL是什么?它有什么特点?
数据定义之基本表的定义/创建、修改和删除
数据定义之索引的创建、修改与删除
数据查询之单表查询。详细解释WHERE、OEDER BY、GROUP BY 和 HAVING
关系的完整性(实体完整性、参照完整性、用户定义的完整性)
事务(包括事务的基本概念和特性解释)
数据库恢复机制
数据库并发控制机制——并发操作带来的数据不一致性问题有哪些
- 系统文章目录
- 并发控制的主要技术
- 封锁(Locking)
- 封锁协议
- 活锁
- 死锁
并发控制的主要技术
产生三种数据不一致性的主要原因是并发操作破坏了事务的隔离性。
并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性 。
并发控制的主要技术有:
- 封锁(Locking)
- 时间戳(Timestamp)
- 乐观控制法
- 多版本并发控制(MVCC)
封锁(Locking)
封锁的概念
:封锁就是事务T在对某个数据对象(例如表、记录等)操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。
锁的类型
:对一个数据对象的操作无非就是读和写两种。所以基本的锁的类型也有两种:
-
排它锁(Exclusive Locks,简记为X锁)又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这样保证了其他事务在T释放A上的锁之前不能再读取和修改A。
-
共享锁(Share Locks,简记为S锁)又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这样保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
封锁协议
在运用X锁和S锁对数据对象加锁时,需要约定一些规则,这些规则为封锁协议(Locking Protocol)。 这个协议规定了何时申请X锁或S锁、持锁时间、何时释放等。
- 一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。所以一级封锁协议只规定了对修改数据的限制。所以可防止丢失修改。但是如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读“脏”数据。
- 二级封锁协议:是在一级封锁协议基础上增加对读数据的限制,也就是说事务T在读取数据R之前必须先对其 加S锁,读完后即可释放S锁。注意这里是读完之后立马就释放S锁,所以虽然可以防止丢失修改和读“脏”数据,但仍然可能出现不可重复读。
- 三级封锁协议:是在一级封锁协议基础上增加事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。在这里,对S锁的持有时间持续到事务结束。所以可以防止丢失修改、读脏数据和不可重复读。
三级协议的主要区别:什么操作需要申请封锁以及何时释放锁(即持锁时间)。
不同的封锁协议使事务达到的一致性级别不同。封锁协议级别越高,一致性程度越高。
活锁
是什么
:如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求……T2有可能永远等待,这就是活锁的情形 。
如何避免
:避免活锁的简单方法就是采用先来先服务的策略。当多个事务请求封锁同一数据对象时,按请求封锁的先后次序对这些事务排队,该数据对象上的锁一旦释放,首先批准申请队列中第一个事务获得锁。
死锁
是什么
:产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死等待。这就形成了死锁的局面。
如何解决
:一是采取一定的措施来预防死锁的发生。二是采用一定手段定期诊断系统中有无死锁,若有那就解除。
-
死锁的预防:
- 一次封锁法:要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。缺点在于对用到的所有数据进行加锁会扩大封锁的范围从而降低了系统的并发度。
- 顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。如在B+树索引结构中,可以规定封锁必须从根结点开始,然后是下一级的子女结点,逐级封锁。缺点在于随着数据的变化,去维护这样的封锁顺序非常困难。
所以在操作系统中广为采用的预防死锁的策略并不太适合数据库的特点,数据库管理系统在解决死锁的问题上更普遍采用的是诊断并解除死锁的方法。
-
死锁的诊断与解除:
- 死锁的诊断有超时法和等待图法。超时法很好理解,就是说如果一个事务的等待时间超过了规定的时限,就认为发生了死锁;等待图法就是定期生成并检测事务等待图中是否存在回路,如果发现图中存在回路,则表示系统中出现了死锁。
- 解除死锁通常采用的方法是选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有的锁,使其它事务能继续运行下去。