数据库是一个共享资源, 它允许多个用户程序并行地存取数据库中的数据, 但是, 如果系统对并行操作不加以控制, 就会存取不正确的数据, 破坏数据库的完整性。在多个事务并发执行的系统中, 主要采取封锁协议来进行处理。
1、数据库的一级、二级、三级封锁协议
2、两段锁协议(Two-phase Locking Protocol)
两段锁协议是指对任何数据进行读写之前必须对数据进行加锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。
- 两段锁协议中两段的含义:事务分为两个阶段,第一个获得封锁称为扩展阶段;第二阶段为释放阶段,也称为收缩阶段。
- 两段锁协议的目的:保证并发调度的正确性。
- 两段锁协议与可串行化:如果事务都遵循两段锁协议,那么它们的并发调度是可串行化。两段锁是可串行化的充分条件,但不是必要条件。如果事务不遵循两段锁协议,它们的并发调度有可能不是可串行化的。
- 说明:采用两段锁协议会有可能产生死锁的情况,因为每个事务不能及时解除被它封锁的数据,可能会导致多个事务互相要求对方已封锁的数据而产生死锁。另外要注意两段锁协议和防止死锁的一次封锁法的异同之处。一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议;但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。
3、活锁、死锁介绍
- 活锁:主要是指事务T1封锁了数据R,事务T2请求封锁数据R,于是T2等待R的封锁被释放。当T1释放数据R上的封锁后,系统批准了T3事务的请求,于是T2仍然等待。如果T3释放后,又批准了T4的请求,那么T2可能会永远等待的现象。
- 死锁:主要是指两个以上的事务分别请求封锁对方已经封锁的数据,导致长期等待而无法继续运行下去的现象。
一般来讲, 死锁是可以避免的, 目前采用的办法有以下几种:
- 预防法: 此种方法是采用一定的操作方式以保证避免死锁的出现, 顺序申请法、一次申请法等即是此类方法。 所谓顺序申请法是指对封锁对象按序编号, 在用户申请封锁时必须按编号顺序(从小到大或反之) 申请, 这样能避免死锁发生。 所谓一次申请法即是指用户在一个完整操作过程中必须一次性申请它所需要的所有封锁, 并在操作结束后一次性归还所有封锁, 这样也能避免死锁的发生。
- 死锁的解除法: 此种方法允许产生死锁, 并在死锁产生后通过解锁程序以解除死锁。 这种方法需要有两个程序, 一是死锁检测程序, 用它测定死锁是否发生, 另一是解锁程序, 一旦经测定系统已产生死锁则启动解锁程序以解除死锁。 有关死锁检测及解锁技术请参阅相应的资料, 这里不做进一步讨论。