死锁和活锁

活锁:

简单描述:

事务T1封锁了数据R

事务T2又请求封锁R,于是T2等待。

T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。

T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求……

T2有可能永远等待,这就是活锁的情形

解决方法:

采用先来先服务的策略

死锁:

简单描述:

事务T1封锁了数据R1

T2封锁了数据R2

T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁

接着T2又申请封锁R1,因T1已封锁了R1T2也只能等待T1释放R1上的锁

这样T1在等待T2,而T2又在等待T1T1T2两个事务永远不能结束,形成死锁

死锁的预防:

  • 一次封锁法

每个事务必须一次将所有要使用的数据全部加锁

 

存在问题:

1.降低系统并发度

2.难于事先精确确定封锁对象

  • 顺序封锁法

顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。

 

存在问题:

1.维护成本:数据库系统中封锁的数据对象极多,并且在不断地变化。

2.难以实现:很难事先确定每一个事务要封锁哪些对象   

  • 死锁的诊断与解除

1.超时法  2.事务等待法(如果事务等待图存在回路,则表示系统中出现了死锁)


死锁的诊断与解除

解除死锁:处理死锁代价最小的事务,将其撤销释放,将其它事务继续运行

可串行化调度

多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同

DBMS并发事务不同的调度可能会产生不同的结果

例:现在有两个事务,分别包含下列操作

      事务T1:读BA=B+1;写回A

      事务T2:读AB=A+1;写回B

现给出对这两个事务不同的调度策略

(a)

T1

T2

Slock B

 

Y=R(B)=2

 

Unlock B

 

Xlock A

 

A=Y+1=3

 

W(A)

 

Unlock A

 

 

Slock A

 

X=R(A)=3

 

Unlock A

 

Xlock B

 

B=X+1=4

 

W(B)

 

Unlock B

假设AB的初值均为2

T1→T2次序执行结果为A=3B=4

串行调度策略,正确的调度

 (b)

T1

T2

 

Slock A

 

X=R(A)=2

 

Unlock A

 

Xlock B

 

B=X+1=3

 

W(B)

 

Unlock B

Slock B

 

Y=R(B)=3

 

Unlock B

 

Xlock A

 

A=Y+1=4

 

W(A)

 

Unlock A

 

 

假设AB的初值均为2

T2→T1次序执行结果为B=3A=4

串行调度策略,正确的调度

T1

T2

Slock B

 

Y=R(B)=2

 

 

Slock A

 

X=R(A)=2

Unlock B

 

 

Unlock A

Xlock A

 

A=Y+1=3

 

W(A)

 

 

Xlock B

 

B=X+1=3

 

W(B)

Unlock A

 

 

Unlock B

 

执行结果与(a)(b)的结果都不同

是错误的调度

T1

T2

Slock B

 

Y=R(B)=2

 

Unlock B

 

Xlock A

 

 

Slock A

A=Y+1=3

等待

W(A)

等待

Unlock A

等待

 

X=R(A)=3

 

Unlock A

 

Xlock B

 

B=X+1=4

 

W(B)

 

Unlock B

执行结果与串行调度(a)的执行结果相同

是正确的调度

 冲突可串行化调度

https://blog.csdn.net/lee18254290736/article/details/79531550            参考大佬的博客

 

冲突操作是指不同的事务对同一个数据的读写操作写写操作其他操作是不冲突操作

不同事务的冲突操作同一事务的两个操作不能交换(Swap)

今有调度Sc1=r1(A)w1(A)r2(A)w2(A)r1(B)w1(B)r2(B)w2(B)

w2(A)r1(B)w1(B)交换,得到:

    r1(A)w1(A)r2(A)r1(B)w1(B)w2(A)r2(B)w2(B)

再把r2(A)r1(B)w1(B)交换:

   Sc2r1(A)w1(A)r1(B)w1(B)r2(A)w2(A)r2(B)w2(B)

Sc2等价于一个串行调度T1T2Sc1冲突可串行化的调度

冲突可串行化调度是可串行化调度的充分条件 

 

3个事务

       T1=W1(Y)W1(X)T2=W2(Y)W2(X)T3=W3(X)

调度L1=W1(Y)W1(X)W2(Y)W2(X) W3(X)是一个串行调度。

调度L2=W1(Y)W2(Y)W2(X)W1(X)W3(X)不满足冲突可串行化。

但是调度L2是可串行化的,因为L2执行的结果与调度L1相同,Y的值都等于T2的值,X的值都等于T3的值

可串行性

1.是并发事务正确调度的准则

2.一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度

 

两段封锁协议

事务含义:

  1. 获得封锁,也称扩展阶段
  2. 释放封锁,也称收缩阶段

事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件。(可冲突化串行调度也只是充分条件)

 

封锁粒度

含义:封锁对象(逻辑单元,物理单元)的大小

逻辑单元:属性值,属性值集,元组,关系,索引项,整个索引,整个数据库。。。。

物理单元:页(数据页,索引页),物理记录。。。。

封锁粒度与系统的并发度和并发控制的开销密切相关:

       1.封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;

       2 .封锁的粒度越小,并发度较高,但系统开销也就越大(根节点是整个数据库,表示最大的数据粒度。叶节点是最小的)

选择封锁粒度:

------同时考虑封锁开销和并发度两个因素,适当选择封锁粒度

       1.需要处理多个关系的大量元组的用户事务:以数据库为封锁单位

       2.需要处理大量元组的用户事务:以关系为封锁单元

       3.只处理少量元组的用户事务:以元组为封锁单位

 

隐式封锁(上级结点加锁)    和    显式封锁(数据对象本身直接加锁)    是多粒度封锁中一个数据对象的方式,效果相同

 

意向锁---提高对某个数据对象加锁时系统的检查效率

对任一结点加基本锁,必须对它的上层结点加意向锁

常用意向锁:

1.意向共享锁(IS)如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。

2.意向排他锁(IX)如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。

3.共享意向排他锁(SIX)如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX

     例: 对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别元组(所以要对该表加IX锁)

死锁和活锁_第1张图片

申请封锁时应该按自上而下的次序进行

释放封锁时则应该按自下而上的次序进行

具有意向锁的多粒度封锁方法优点:

提高了系统的并发度

减少了加锁和解锁的开销

在实际的数据库管理系统产品中得到广泛应用

 

 

v数据库的并发控制以事务为单位

v数据库的并发控制通常使用封锁机制

 

v活锁: 先来先服务

v 死锁:

预防方法

      Ø一次封锁法

      Ø顺序封锁法

死锁的诊断与解除

      Ø超时法

      Ø等待图法

你可能感兴趣的:(数据库(Oracle))