并发控制
并发控制
9.1并发操作带来的问题
- 丢失修改:两个业务对同一个数据进行修改,导致事务A对数据库的修改被事务B的修改所覆盖。
- 不可重复读:事务对同一数据进行两次读取的结果不同。原因是两次读取的间隙数据被另一个事务修改了
- 读脏数据:事务读取了其他事务修改的数据,但是这个修改后来又被撤销了,这个数据就是被其他事务丢弃的数据
并发控制技术:封锁、时间戳、乐观控制法、多版本并发控制
9.2并发调度的可串行性
多个事务的并发执行是正确的,当且仅当其结果与某一次串行执行的结果一致,称这种调度为可串行化调度。
可串行性是并发事务正确性的准则。即一个并发调度,当且仅当它是可串行化的才认为是正确调度。
9.3 封锁
排它锁(Exclusive Locks, 简称X锁):也称为写锁,用于对数据进行写操作时进行锁定。如果事务T对数据A加上X锁后,就只允许事务T对数据A进行读取和修改,其他事务对数据A不能再加任何锁,也不能读取和修改数据A,直到事务T释放A上的锁。
共享锁(Share Locks, 简称S锁):也称为读锁,用于对数据进行读操作时进行锁定。如果事务T对数据A加上了S锁后,事务T就只能读数据A但不可以修改,其他事务可以再对数据A加S锁来读取,只要数据A上有了S锁,任何事务都只能再对其加S锁读取而不能加X锁修改。
封锁协议:
一级封锁协议:是指事务T在修改数据A之前必须先对其加X锁,直到事务结束才释放X锁。解决了丢失修改的问题,保证事务T是可恢复的。不能保证可重复读和不读脏数据。
二级封锁协议:是一级封锁协议加上事务T在读取数据A之前必须对其加上S锁,读完后即可释放S锁。解决了读脏数据的问题。不能保证可重复读。
三级封锁协议:是一级封锁协议加上事务T在读取数据A之前必须对其加上S锁,直到事务结束才释放S锁。解决了不可重复读的问题。
9.4 两段锁协议
两段锁协议(2PL):是指同一事务对任何数据进行读写之前必须对该数据加锁;在释放一个封锁之后,该事务不再申请和获得任何其他封锁。(一个事物申请锁的时候,必须全部申请下来。释放锁的时候也必须全部释放。不能先申请一个锁释放一个锁,然后继续申请释放)
‘两段’ 含义:事务分为两个阶段。第一阶段是获得封锁,也称为扩展阶段。第二阶段是释放封锁,也称为收缩阶段
如果遵循两段锁协议,一定是可串行化的;不遵循两段锁协议,可能是可串行化的,也可能不是;(充分不必要)
注: 采用两段锁协议也有可能产生死锁,这是因为每个事务都不能及时解除被封锁的数据,可能会导致多个事务都要求对方已经封锁的数据而不能继续运行。
9.5 多粒度封锁
封锁的粒度:
封锁对象的大小称为封锁粒度。封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;反之,封锁的粒度越小,并发度越高,但系统开销也就越大。
多粒度树:
以树形结构来表示多级封锁粒度。根结点是整个数据库,表示最大的数据粒度。叶结点表示最小的数据粒度。
例:三级粒度树。根结点为数据库,数据库的子结点为关系,关系的子结点为元组。
多粒度封锁协议:
允许多粒度树中的每个结点被独立地加锁。对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁。