oracle数据库并发二

阻塞

如果一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking )。这样一来,请求的会话会被阻塞,它会“挂起”,直至持有锁的会话放弃锁定的资源。

数据库中有5 条常见的DML 语句可能会阻塞,具体是:INSERTUPDATEDELETEMERGESELECT FOR UPDATE 。对于一个阻塞的SELECT FOR UPDATE ,解决方案很简单:只需增加NOWAIT 子句,它就不会阻塞了。

例子

时间点

Session1

Session2

T1

开始事务

 

T2

 

开始事务

T3

Update A set col1=2 where id=1

获得id1 的行的排它锁(X

 

T4

 

Update A set col1=5 where id=1

等待session1 释放id1 的行的排它锁(X

T5

commit

 

T6

 

commit

在上面的例子中

Session1T3 时刻获得id1 的行的排它锁(X),T4 时刻,session2 也要更新该行,也要在行上加排它锁(X ),由于session1 的事务还没有提交,因此session2 这个时候就被阻塞了,只到session1 的事务提交或回滚后session2 也获得此行的排它锁(X )使事务得以进行。

死锁

       如果你有两个会话,每个会话都持有另一个会话想要的资源,此时就会出现死锁(deadlock )。

例子

时间点

Session1

Session2

T1

开始事务

 

T2

 

开始事务

T3

Update A set col1=2 where id=1

获得id1 的行的排它锁(X

 

T4

 

Update B set col1=5 where id=4

获得id4 的行的排它锁(X

T5

Update B set col1=6 where id=4

等待session2 释放id4 的行的排它锁(X

 

T6

 

Update A set col1=8 where id=1

等待session1 释放id1 的行的排它锁(X

T7

commit

 

T8

 

commit

在上面的例子中

    Session1T3 时刻获得表Aid1 的行的排它锁(X),T4 时刻,session2 获得表Bid4 的行的排它锁(X),T5 时刻,session1 要更新表Bid4 的行,要在行上加排它锁(X ),由于session2 的事务还没有提交,因此session1 这个时候就被阻塞了,T6 时刻session2 要更新表Aid1 的行,要在行上加排它锁(X ),由于session1 的事务还没有提交,因此session2 这个时候就被阻塞了,这时两个会话都被对方阻塞了于是死锁就发生了。

    oracle 中,oracle 会自己检测死锁,一旦检测到就会回滚该语句,在这个例子中oracle 会在T6 时刻检测到死锁并回滚该语句,但session2T4 上仍然保持着锁,因此session1 还是不能继续进行。

    即使对同一个表操作也会出现死锁的情况

时间点

Session1

Session2

T1

开始事务

 

T2

 

开始事务

T3

Update A set col1=2 where id=1

获得id1 的行的排它锁(X

 

T4

 

Update A set col1=5 where id=4

获得id4 的行的排它锁(X

T5

Update A set col1=6 where id=4

等待session2 释放id4 的行的排它锁(X

 

T6

 

Update A set col1=8 where id=1

等待session1 释放id1 的行的排它锁(X

T7

commit

 

T8

 

commit

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值