不一致性
- 修改丢失(lost update) - 两个事务同时修改同一数据
- 不可重复读 (non-repeatable read) - 不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。
- 事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时,得到与前一次不同的值
- (幻影(phantom row)现象)
- 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录消失了
- 事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。
- 读脏数据 (dirty read)
- 事务T1修改某一数据,并将其写回磁盘。事务T2读取同一数据后,T1由于某种原因被撤销。这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致。T2读到的数据就为“脏”数据,即不正确的数据 。
封锁
- 排他锁(exclusive locks) X锁 写锁
- 共享锁(share locks) S锁 读锁
- 封锁协议:
- 一级封锁协议:修改数据前加X锁,直到事务结束后才能释放 -> 防止修改丢失
- 二级封锁协议:一级锁协议 + 读取数据前加S锁,读取完即可释放 -> 防止修改丢失 + 读脏数据
- 三级封锁协议:一级锁协议 + 读取数据前加S锁,事务结束时释放 -> 防止修改丢失 + 读脏数据 + 不可重复读
- 活锁:“一直被插队”
- 策略:采用先来先服务的策略
- 死锁:相互等待
- 预防死锁:
- 一次封锁法:
- 要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行
- 缺点:降低系统并发度,难于事先精确确定封锁对象
- 顺序封锁法
- 顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。
- 缺点:维护成本高,难以实现
- 一次封锁法:
- 诊断并解除死锁 - 普遍采用
- 超时法
- 事务等待图法
- (解除死锁:选择一个处理死锁代价最小的事务,将其撤消释放此事务持有的所有的锁,使其它事务能继续运行下去)
- 预防死锁:
可串行化调度
- 多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同
- 可串行化调度的充分条件:一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc‘,如果Sc’是串行的,称调度Sc为冲突可串行化的调度。(一个调度是冲突可串行化,一定是可串行化的调度)
- 冲突操作:
- Ri (x)与Wj(x) 事务Ti读x,Tj写x
- Wi(x)与Wj(x) 事务Ti写x,Tj写x
- 不同事务的冲突操作和同一事务的两个操作不能交换
- 两段锁协议:指所有事务必须分两个阶段对数据项加锁和解锁
- 在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁 (第一阶段是获得封锁,也称为扩展阶段:事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁
) - 在释放一个封锁之后,事务不再申请和获得任何其他封锁(第二阶段是释放封锁,也称为收缩阶段:事务可以释放任何数据项上的任何类型的锁,但是不能再申请任何锁
)
- 在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁 (第一阶段是获得封锁,也称为扩展阶段:事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁
- (两段锁协议与防止死锁的一次封锁法:一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议。但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁)
- 封锁对象的大小称为封锁粒度(Granularity)
- 多粒度树:以树形结构来表示多级封锁粒度,根结点是整个数据库,表示最大的数据粒度,叶结点表示最小的数据粒度。
- 多粒度封锁中一个数据对象可能以两种方式封锁:显式封锁和隐式封锁:
- 意向锁(intention lock):对任一结点加基本锁,必须先对它的上层结点加意向锁
- 意向共享锁(intention share lock) IS :其后裔节点要读(加S锁)
- 意向排他锁(intention exclusive lock)IX : 其后裔节点要写(加X锁)
- 共享意向排他锁(share intent exclusive lock)SIX :表示对它加S锁,再加IX锁,即SIX = S + IX。表示该事务要读整个表(所以要对该表加S锁),同时会更新个别元组(所以要对该表加IX锁)。
- 锁的强度:锁的强度是指它对其他锁的排斥程度。一个事务在申请封锁时以强锁代替弱锁是安全的,反之则不然
- X锁不相容的锁 包含了 SIX锁不相容的所有锁 --> X 强于 SIX
- X > SIX > (S / IX) > IS
- 具有意向锁的多粒度封锁方法:申请封锁时应该按自上而下的次序进行.释放封锁时则应该按自下而上的次序进行.