不可重复读是指事务T1读取数据后,事务T2 执行更新操作,使T1无法再现前一次读取结果。 不可重复读包括三种情况: (1)事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时,得到与前一次不同的值
不可重复读
(2)事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录消失了
(3)事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。
后两种不可重复读有时也称为幻影现象(Phantom Row)
读“脏”数据
读“脏”数据是指:
事务T1修改某一数据,并将其写回磁盘
事务T2读取同一数据后,T1由于某种原因被撤销
这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致
T2读到的数据就为“脏”数据,即不正确的数据
数据不一致性:由于并发操作破坏了事务的隔离性
并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性
并发控制的主要技术
封锁(Locking)
时间戳(Timestamp)
乐观控制法
商用的DBMS一般都采用封锁方法
封锁(Locking)
并发控制的主要技术
封锁(Locking)
时间戳(Timestamp)
乐观控制法
商用的DBMS一般都采用封锁方法
一个事务对某个数据对象加锁后究竟拥有什么样的控制由封锁的类型决定。
基本封锁类型
排它锁(eXclusive Locks,简记为X锁)
共享锁(Share Locks,简记为S锁)
排它锁又称为写锁
若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁
保证其他事务在T释放A上的锁之前不能再读取和修改A
共享锁又称为读锁
若事务T对数据对象A加上S锁,则其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁
保证其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改
在锁的相容矩阵中:
最左边一列表示事务T1已经获得的数据对象上的锁的类型,其中横线表示没有加锁。
最上面一行表示另一事务T2对同一数据对象发出的封锁请求。
T2的封锁请求能否被满足用矩阵中的Y和N表示
Y表示事务T2的封锁要求与T1已持有的锁相容,封锁请求可以满足
N表示T2的封锁请求与T1已持有的锁冲突,T2的请求被拒绝
活锁和死锁
封锁技术可以有效地解决并行操作的一致性问题,但也带来一些新的问题
死锁
事务T1封锁了数据 R1 T2封锁了数据 R2 T1又请求封锁 R2 ,因T2已封锁了 R2 ,于是T1等待T2释放 R2 上的锁 接着T2又申请封锁 R1 ,因T1已封锁了 R1 ,T2也只能等待T1释放 R1 上的锁 这样T1在等待T2,而T2又在等待T1,T1和T2两个事务永远不能结束,形成死锁
两类方法
1. 预防死锁
2. 死锁的诊断与解除
活锁
事务T1封锁了数据R 事务T2又请求封锁R,于是T2等待。 T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。 T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求…… T2有可能永远等待,这就是活锁的情形
避免活锁:采用先来先服务的策略
当多个事务请求封锁同一数据对象时
按请求封锁的先后次序对这些事务排队
该数据对象上的锁一旦释放,首先批准申请队列中第一个事务获得锁
死锁的预防
产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死等待。
预防死锁的发生就是要破坏产生死锁的条件
预防死锁的方法
一次封锁法
顺序封锁法
要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行
存在的问题
降低系统并发度
难于事先精确确定封锁对象
顺序封锁法是预先对数据对象规定一个封锁顺序,按顺序编号,所有事务都按这个编号顺序申请封锁。
顺序封锁法存在的问题
维护成本
数据库系统中封锁的数据对象极多,并且在不断地变化。
难以实现:很难事先确定每一个事务要封锁哪些对象
结论
在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点
DBMS在解决死锁的问题上更普遍采用的是诊断并解除死锁的方法
死锁的诊断
超时法
如果一个事务的等待时间超过了规定的时限,就认为发生了死锁 优点:实现简单 缺点 有可能误判死锁 时限若设置得太长,死锁发生后不能及时发现
事务等待图法
用事务等待图动态反映所有事务的等待情况 事务等待图是一个有向图G=( T ,U) T 为结点的集合,每个结点表示正运行的事务 U为边的集合,每条边表示事务等待的情况 若T1等待T2,则T1,T2之间划一条有向边,从T1指向T2
并发控制子系统周期性地(比如每隔数秒)生成事务等待图,检测事务。如果发现图中存在回路,则表示系统中出现了死锁。
$(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘ ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i ‘).text(i)); }; $numbering.fadeIn(1700); }); });数据库 - 并发控制
标签:一致性 并发 控制 系统 数据库