当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

锁的粒度与死锁概率

发表于: 2015-05-23   作者:cfyme   来源:转载   浏览次数:
摘要: 首先,我们要定义下什么是“锁的粒度”:所谓粒度就是作用范围,锁的粒度就是锁的作用范围。数据库中锁的粒度从高到低依次划分为:数据库、表、页、行。什么是死锁,顺带说一下吧,当多个操作竞争资源,每个操作都无法获得全部所需资源时,系统进入死锁,如无外力作用,系统将无限等待下去,死锁的四个必要条件:(1) 互斥条件:一个资源每次只能被一个进程使用。(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得

首先,我们要定义下什么是“锁的粒度”:所谓粒度就是作用范围,锁的粒度就是锁的作用范围。数据库中锁的粒度从高到低依次划分为:数据库、表、页、行。
什么是死锁,顺带说一下吧,当多个操作竞争资源,每个操作都无法获得全部所需资源时,系统进入死锁,如无外力作用,系统将无限等待下去,死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
打破任何一个条件就不会发生死锁。

我们先来看一个生活场景:
有两个文具盒,一个放的是笔(圆珠笔、铅笔等等),一个放的是修正工具(橡皮擦、改正带等等).
现在有两个人,他们要画图,可能需要的物品当然有笔和修正工具。
假设我们用全局的独享,就是两个文具盒都只能同时被一个人拥有,一个人来拿笔,连带修正工具一起归他,这样绝对不会发生图画不下去的问题,因为所要的工具都会一次性给同一个人。但是问题也很严重,资源严重浪费,因为笔和橡皮擦肯定不会同时使用,也不会同时用2支笔。
假设我们用的是文具盒的独享,就是同时一个文具盒只能被一个人拥有,一个人要笔,整个放笔的文具盒都给他,一个人要修正图画,则整个放修正工具的文具盒都给他。这可能出现的问题就是,一个人想,我要画图,橡皮擦肯定要,橡皮擦的文具盒正好在,就先把这个文具盒拿下,等笔盒回来了再继续画。另一个人拿了笔盒,画了一会要修正,一看,放橡皮擦的文具盒没了,就等文具盒放回来。这样两个人就无限等待了,只要其中一个人看到东西不全就不拿,就不会无限等。
假设我们用的是物品独享,就是一支笔、一个橡皮擦只能被一个人拥有,一个人要画图,就拿一支笔,要改就拿一个橡皮擦或者改正带。除非只有一支笔,否则不会出现无限等待。当然,只有一支笔跟独享一个文具盒没区别。


例子中的独享就是锁的概念。

再来看数据库中的实例:
假设有A,B两个数据库,A库有A1,A2两个表,B库也有B1和B2两个表,每个表都有都有N条记录(N>1).
现在有两个操作P1和P2并发,我们来看一个场景:
P1要操作A1表的一行和B2表的一行,P2要操作A2表的一行和B1表的一行。
现在假设我们用库锁,P1先行,A库被锁住,P2后行,先锁住了B库,P1再去锁B库,已经被P2锁住了,P2去锁A库,被P1锁住了,这样P1,P2就陷入死锁,都占用部分资源。
假设我们用的是表锁呢,P1先行,A1被锁住,P2后行,A2被锁住,P1再锁B1,P2再锁B2,怎么也不会发生死锁。
采用行锁的话就更不会死锁了,操作的表都不同。
看到这里,大家就说,锁的粒度越大,越容易死锁,真的吗?那我再来个最大的锁,实例锁,一次性锁住整个实例,P1先行,整个实例被锁住,P2被阻塞,等P1操作完P2再来,肯定不会死锁,为什么?因为这已经退化成串行操作了。

也就是说,虽然一般情况下锁的粒度越大,死锁概率越大,但是,当锁的粒度成为全局锁,把操作变成串行后,就不一样了,根本不会死锁。

我们把P1和P2操作改一下,P1操作A1表的i行和A2表的j行,P2操作A1表的j行和A2表的i行(i<>j),再来看:
假设我们使用库锁,P1先行,A库就锁住,P2阻塞,P1完成P2锁A库,不会死锁。
假设我们使用表锁,P1先行,A1表锁住,P2后行,A2表锁住,P1再去锁A2表,已经被P2锁了,死锁发生。
假设我们使用行锁,P1先行,锁住A1表第i行,P2后行,锁住A1表第j行,P1再锁A2表j行,P2再锁A1表j行,完成操作。

也就是说,不能就认为所有情况都是锁的粒度越大死锁概率越大,而是要看操作的粒度,如果锁的粒度比操作的粒度大或相同,操作就会变成串行,根本不可能发生死锁。

顺便说以下,数据库中并行操作的情况很多,为什么很少发生死锁呢,因为只要打破死锁四个条件任意一个,就可以避免死锁,只会发生阻塞,一个操作释放资源后就可以继续进行。
方法很多,例如把锁的粒度提高到跟操作的粒度大,并发一个表,我就一次锁一个表,并发一个库,我就一次锁一个库,这实际上是什么呢,就是把并行弄成串行了,一般没人这么做,并发只有1,效率太低。
一般是多管齐下避免死锁,一是使用不同等级的锁,例如意向锁,互斥锁等,其实就是打破死锁第一条件——互斥条件,资源某些时候可以共享,例如读锁可以共享读,不过因为还是存在互斥锁,依然可能死锁。
第二就是可以按顺序锁资源,例如锁表只能按A->B->C的顺序锁,如果我要A,B表,锁了A表后发现B表已经被锁了,就释放A表的锁(或者使用意向锁),延时再尝试,直到所有资源都可以锁住(互斥锁/共享锁),这就是打破了死锁第二条件——请求与保持条件,不能获得全部资源就先释放锁,等能获得了再说,这样操作可以完全避免死锁。

 

转载地址:http://religiose.iteye.com/blog/1678760

锁的粒度与死锁概率

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Introduction to Transaction Locks in InnoDB Storage Engine https://blogs.oracle.com/mysqlinnod
用一个锁Lock一组相关的对象 有时,需要按组来修改多个对象. 这样,在需要锁住其中一个的时候,必须连
用一个锁Lock一组相关的对象 有时,需要按组来修改多个对象. 这样,在需要锁住其中一个的时候,必须连
锁这东西是纯概念性的东西,但是作用又非常大。 以前整理过两篇文章,今天又看了点书,觉得还不是很
导读:本文就SQL SERVE和ORACLE常出现的锁和死锁的检测和解决方法进行了全面比较,比较内容包括锁的
4、锁争用的监测和解决   ORACLE:   ORACLE提供了有用的锁的动态性能视图V$LOCK和V$locked_OBJE
在java多线程编程中,一不小心就会引起活性危险(liveness hazard),需要非常谨慎。 liveness可以翻
8 概率
由于快要交概率论文了,先刷刷概率题,然后糊弄一篇上去就算了= = 自己挂了一场概率比赛,链接为htt
背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作。经过DB
原文: 阻塞与死锁(二)——各种操作对锁的申请 如何监视锁的申请、持有和释放: 在着手分析、处理阻
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号