ITPUB??ì3
2010数据库技术大会
ITPUB论坛 » Oracle专题深入讨论 » 我对ORACLE数据锁的一点体会

您有 2 条公共消息
  • 来自: 公共消息 标题: 新开"PLM/PDM产品 ... 内容: 讨论范围包括:产品研发管理(PDM),产品生命周期管理(PLM),工艺/ ...
  • 来自: 公共消息 标题: 2010数据库技术大 ... 内容: “2010数据库技术大会”将于2010年4月2日~4月3日,在北京歌华开元大酒 ...

    标题: [精华] 我对ORACLE数据锁的一点体会
    在线/呼叫 ZALBB


    精华贴数 8
    个人空间 0
    技术积分 40298 (23)
    社区积分 18229 (107)
    注册日期 2001-10-15
    论坛徽章:129
          
          

    发表于 2004-9-24 17:54 
    我对ORACLE数据锁的一点体会

    该贴的部分内容是针对帖中带的附件(一位大侠关于锁的理解),提的理解/疑问,
    大家在读此贴前,请先阅读该文。


    先说说各类型的锁:共享锁,排它说,共享排它锁(对表定义共享,对表操作的记录排它)。

    1、我对文章中意向锁的理解,就是:对表的记录进行操作之前,先对表定义(包括表结构、约束等)
       加了共享锁,这是为了避免对表的DDL操作。

       比如:当你往TAB1插入一条记录时,该表的一个字段COL8是允许为空的,插入这条记录的该字段
       的值是空的,此时,若不对该表定义加共享锁,则另外一SESSION对TAB1.COL8加非空约束,
       那该表结构修改就与插入的记录发生冲突了。所以,当执行DML操作是,必定对操作的表加DDL
       共享锁。

       这是我理解的意向锁。
       
    2、文章中提及,记录行是无共享锁。我对此观点表示不同:当插入/修改子表时,对应的父表的主键
       记录应该被加共享锁,因为此时要保证父键的存在。经测试,当插入/修改/删除子表时,父表
       确实被加了SS锁,此时可以对父表的主键做插入动作,但不允许做修改/删除。这符合逻辑。因为
       插入操作并不影响主外键的关系。但删除/修改则可能。

       
    3、SHARE VS ROW SHARE有什么区别?

       我猜想:ROW SHARE是(级别=2)对表加表定义共享锁,SHARE(级别=4)是对表定义及表“所有”的
       记录加共享锁。但这样就有问题:1、SELECT FOR UPDATE产生TM=2、对查询出来的记录产生TX=6的
       锁,那这样应该与:表“所有”的记录加共享锁 相冲突了?但实际并不是,实际上,当对表加SHARE
       锁时,还是可以对该表执行 SELECT FOR UPDATE,但却不可以执行DML操作!
       
       现我只能这样理解,虽然产生了TX=6 的事务锁,但实际上,还并没有真正修改记录。和真正的
       INSERT ,UPDATE, DELETE 操作还是有区别的。也就是:SELECT FOR UPDATE这个锁有点特别:
       对加了共享锁的记录,还可以SELECT FOR UPDATE,但若想执行DML语句,则不可以,因为该表的
       “所有” 记录都加了共享锁。
       
    4、若照第3点的理解,那SRX就是对表加共享锁,对表的所有记录加排它锁。这是我的猜测,不知道
       在什么地方会使用上这种锁。

    总结:查看了ORACLE的文档,其并不解释如何定义的各级别的锁,为什么会这样定义,理由、用途何
    在?现在我想使用各类型锁,来对ORACLE锁的各级别定义说明:

    0、无
    1、NULL,可以某些情况下,如分布式数据库的查询会产生此锁。
    2、SS,表结构共享锁
    3、SX,表结构共享锁+被操作的记录的排它锁
    4、S, 表结构共享锁+所有记录共享锁
    5、SRX 表结构共享锁+所有记录排它锁
    6、X   表结构排它锁+所有记录排它锁


    其中 SELECT FOR UPDATE是比较特殊的一种情况:由于其不修改记录,所以对这些记录而言,
    并未产生真正的排它锁,这与DML操作产生的排它锁相比,是有差别的,但由于不允许在这些记录“再”
    加SELECT FOR UPDATE,所以,也不是纯粹的共享锁,我认为其是介于共享锁和排它锁之间的一种特殊
    的情况,因此,ORACLE在对表加了S锁后,还允许对该表执行SELCT FOR UPDATE,但实际上,此时此语句
    已经无意义了,因为加了S锁的表不允许DML操作,故,此语句于普通的SELECT 语句无差别。

    请拍砖。




    ZALBB 上传了这个附件:
    2004-9-24 17:54
      下载次数: 4052
    oracle多粒度封锁机制研究(论坛).doc (139.5 KB)
     
    __________________
    对内,共匪什么都要,就是不要脸;对外,共匪什么都不要,就是要脸。
    只看该作者    顶部
    离线 grassbell
    曾经的深入讨论区斑竹:)


    精华贴数 9
    个人空间 0
    技术积分 11856 (126)
    社区积分 370 (2075)
    注册日期 2003-6-13
    论坛徽章:6
    管理团队成员ITPUB北京九华山庄2008年会纪念徽章参与2007年甲骨文全球大会(中国上海)纪念管理团队2006纪念徽章会员2006贡献徽章授权会员
          

    发表于 2004-9-26 00:17 
    1、我对文章中意向锁的理解,就是:对表的记录进行操作之前,先对表定义(包括表结构、约束等)
    加了共享锁,这是为了避免对表的DDL操作。

    比如:当你往TAB1插入一条记录时,该表的一个字段COL8是允许为空的,插入这条记录的该字段
    的值是空的,此时,若不对该表定义加共享锁,则另外一SESSION对TAB1.COL8加非空约束,
    那该表结构修改就与插入的记录发生冲突了。所以,当执行DML操作是,必定对操作的表加DDL
    共享锁。

    这是我理解的意向锁。

    ~~~~~~~~~~~~~~~~~~~~~~

    从你提供的文章中理解,意向锁的作用应该是减少开销,也就是说不必要扫描表中每一行的加锁情况,而直接从表上加载的意向锁的情况得到表中行锁的情况。

    而你举的例子,应该是文章中没有提到的DDL lock( dictionary locks),有待考察。

    anyway,


    __________________
    不是自己的,多研究,多做实验,把心得写出来,变成自己的

    欢迎访问Alibaba DBA 团队Blog: www.alidba.net

    http://twitter.com/chndonny
    只看该作者    顶部
    离线 jeffli73
    侠之大者


    精华贴数 2
    个人空间 133
    技术积分 10583 (145)
    社区积分 21 (8950)
    注册日期 2002-6-17
    论坛徽章:1
    授权会员     
          

    发表于 2004-9-26 01:28 
    我感到非常遗憾

    我感到非常遗憾,楼主没有完全看懂我写的那篇《Oracle多粒度封锁机制研究》,这可能主要是本人水平有限、表达不清所致。

    要理解Oracle的封锁机制,关键要搞清为什么要“多粒度”及为什么要引入“意向锁”。

    其实生活中有很多类似的问题,我先描述一个,我把它命名为“艺术中心问题”,如果此问题与哪位计算机界前辈已描述的问题有类似之处,纯属本人孤陋寡闻,而绝非有意抄袭。


    一个艺术中心占地很广(我们把它类比做数据库),有许多独立的建筑-艺术馆(艺术馆相当于数据库中的“表”),各个艺术馆中又有许多展室(相当于表中的记录),为了使各个艺术馆得到有效的管理,对进出艺术馆的人员进行了分类并对他们各自的行为做了如下限制:
    A:一般观众:,在任何情况下,他们可以自由进出艺术馆的各个展室,没有限制,但他们只能观看;
    B:不同工种的维修工人:他们可以进入展室进行检查或维修,但是在某一时刻,只能有一个工种的工人在某个展室进行维修(这主要是为了安全,比如油漆工与电焊工如果同时作业,可能会引起火灾);
    C:重要来宾(比如联合国世界文化遗产的评审官员):为了保证这些重要来宾的参观效果,在他们参观期间,不允许任何的维修、展室调整(下面介绍)等工作,但仍然可以接待一般观众;
    D:展室调整人员:由于展室调整会涉及多个展室,所以在调整期间,不允许对任何展室进行维修,也不接待任何重要来宾;

    基本情况就是这样,现在一位名叫Oracle的老师问他班上的小学生,如果你是各个艺术馆的管理人员,你将采取何种措施来保证这些规定的执行。

    一名叫TOM的小学生非常聪明,考试总考第一,平时也爱出个风头,他第一个举手回答问题,说:这个容易,
    1)对于一般观众,他们手持通票;
    2)对于重要来宾,我先发给他们印有‘S’的胸卡;
    3)对于维修工与展室调整人员,我先发给他们印有‘X’的胸卡;

    到时我会守在艺术馆的门口,对于:
    手持通票的人,我将一律放行;
    对于佩带‘S’胸卡的人,我要检查一下我手里是否有‘X’的胸卡,如果有,对不起,他们只能等待,如果没有,他们可以进入,并将其胸卡留在我这里;他们出去时,我将胸卡还给他们;
    对于佩带‘X’胸卡的人,我要检查一下我手里是否有‘S’或‘X’的胸卡,如果有,对不起,他们只能等待,如果没有,他们可以进入,并将其胸卡留在我这里;他们出去时,我将胸卡还给他们。

    老师赞许地点了点头,说很好,TOM明天你就去实践一下吧。

    第二天,TOM早早来到某个艺术馆的门口等候人们的到来,一般观众很多,TOM没有对他们进行任何限制,秩序很好,TOM非常高兴。
    这时候,一个佩带‘X’胸卡的油漆工A走了过来,TOM检查了一下,发现还没有留下任何胸卡,就让油漆工进去了,并留下了他的胸卡。
    又过了一阵子,另一个佩带‘X’胸卡的电焊工B过来了,TOM检查发现自己这里已经有一个‘X’胸卡了,他便非常有礼貌的拦住了这名工人,告诉他只有等到已经进去的工人出来领走自己的胸卡后他才能进入,B无奈只好等待。等了大约1个小时,A终于出来了,B问A刚才在哪个展室施工,A说在101,B一听气就不打一处来,他质问TOM,我要去102,艺术馆只是规定我们不能同时在一个展室工作,而我们要去不同的展室,你为什么不让我进去。
    TOM听了,很委屈,说我只记录你们进出艺术馆的情况,又不记录你们进出展室的情况,谁知道你们会不会冲突,保险起见,你来晚了只能等着。


    今天已经很晚了,这个小故事先写到这里,我想很多朋友已明白我的用意,TOM实际上采用的是单粒度的封锁方法,而且封锁的粒度比较大,以后我再续写另一种单粒度的方法,及Oracle老师的做法,不过到时也可能有的朋友已经帮我写好了。


    __________________
    安能摧眉折腰事权贵,使我不得开心颜天生我才必有用,千金散尽还复来个人BLOG: http://blog.china-pub.com/blog.asp?name=jefflee包括数据库、软件工程、电信及其它方面的个人感悟,如有兴趣,欢迎访问
    只看该作者    顶部
    在线/呼叫 ZALBB


    精华贴数 8
    个人空间 0
    技术积分 40298 (23)
    社区积分 18229 (107)
    注册日期 2001-10-15
    论坛徽章:129
          
          

    发表于 2004-9-26 10:50 
    jeffli73,请看看我的问题:

    问:我说的那个意向锁,和你说的有差别吗?差别在哪里?
    2、你如何理解ORACLE定义的7个级别的锁?为什么要这样定义?


    __________________
    对内,共匪什么都要,就是不要脸;对外,共匪什么都不要,就是要脸。
    只看该作者    顶部
    在线/呼叫 ZALBB


    精华贴数 8
    个人空间 0
    技术积分 40298 (23)
    社区积分 18229 (107)
    注册日期 2001-10-15
    论坛徽章:129
          
          

    发表于 2004-9-26 11:02 


    QUOTE:
    最初由 grassbell 发布
    1、我对文章中意向锁的理解,就是:对表的记录进行操作之前,先对表定义(包括表结构、约束等)
    加了共享锁,这是为了避免对表的DDL操作。

    比如:当你往TAB1插入一条记录时,该表的一个字段COL8是允许为空的,插入这条记录的该字段
    的值是空的,此时,若不对该表定义加共享锁,则另外一SESSION对TAB1.COL8加非空约束,
    那该表结构修改就与插入的记录发生冲突了。所以,当执行DML操作是,必定对操作的表加DDL
    共享锁。

    这是我理解的意向锁。

    ~~~~~~~~~~~~~~~~~~~~~~

    从你提供的文章中理解,意向锁的作用应该是减少开销,也就是说不必要扫描表中每一行的加锁情况,而直接从表上加载的意向锁的情况得到表中行锁的情况。

    而你举的例子,应该是文章中没有提到的DDL lock( dictionary locks),有待考察。

    anyway,


    文章是在混沌的思维中,以我的理解写的,有些地方交代不清楚。
    是要有些基础才能明白。

    不过,你这么一说,我发现文章中引申出可能意向锁所举的例子
    好象不正确:

    比如一个事务要在一个表上加S锁,如果表中的一行已被另外的事务加了X锁,那么该锁的申请也应被阻塞。

    比如:修改了表的一行记录,那只是在表上加S锁,同时对修改
    的记录加了X所,但这并不影响另外的会话对该表加S锁,对其余
    的记录加X锁。

    但这也可能是我的理解与jeffli73有差别。

    我主要的目的是想了解ORACLE为什么要这样定义这7个级别的锁,
    如何用共享锁,排它锁,共享排它锁等来理解这7级锁的定义。


    __________________
    对内,共匪什么都要,就是不要脸;对外,共匪什么都不要,就是要脸。
    只看该作者    顶部
    在线/呼叫 ZALBB


    精华贴数 8
    个人空间 0
    技术积分 40298 (23)
    社区积分 18229 (107)
    注册日期 2001-10-15
    论坛徽章:129
          
          

    发表于 2004-9-26 11:10 
    要说清楚的是:共享锁,排它锁都体现在记录(数据)和表结构上,但由于记录是存储在
    在表中的,脱离表结构来谈记录(数据)是无意义的,所以,我开头的文章里
    没有单独的记录(数据)共享锁,而是要结合表结构,便这样理解这7个级别的锁。


    __________________
    对内,共匪什么都要,就是不要脸;对外,共匪什么都不要,就是要脸。
    只看该作者    顶部
    离线 jeffli73
    侠之大者


    精华贴数 2
    个人空间 133
    技术积分 10583 (145)
    社区积分 21 (8950)
    注册日期 2002-6-17
    论坛徽章:1
    授权会员     
          

    发表于 2004-9-26 22:57 
    ZALBB朋友性子比较急

    不想等我把故事将完,今天有些事,我就先直接回答你的问题,等有时间再把故事讲完.

    首先,需要说明,ORACLE的数据锁在两个级别上,表级与行级,这就是所谓的"多粒度",为什么要多粒度,就是因为单粒度都有各自的缺陷,光是表级,封锁粒度太大,并发性不好(如故事中TOM的方案);光是行级,对有些情况开销太大,所以要有多粒度.

    而最经典的锁类型就是两种,S与X,但是为了效率,某个事务锁住某一记录,ORACLE也让它在行的上级(表级)做一下标识,这就是所谓的"意向锁",很自然就有了RS(表示有个别行别加S锁)与RX(表示有个别行别加X锁),而这两种意向锁(RS与RX)与两种实体锁(S与X)理论上有4种组合,实际只有1种有实际意义,即SRX.
    这样在表级就有了5种锁,S,X,RS,RX,SRX,表级锁作用主要有2个:保护表结构与保护数据;
    在行级,ORACLE实际上只有X锁(2个SELECT FOR UPDATE不能同时针对同一行),行级锁的作用就是保护数据.

    另外,我的<ORACLE多粒度封锁机制研究>已经有第2个版本,比第一版增加了将近1倍的内容,据tigerfish说在他们准备在新出的书中选用,我想现在可能不便公开.


    __________________
    安能摧眉折腰事权贵,使我不得开心颜天生我才必有用,千金散尽还复来个人BLOG: http://blog.china-pub.com/blog.asp?name=jefflee包括数据库、软件工程、电信及其它方面的个人感悟,如有兴趣,欢迎访问
    只看该作者    顶部
    在线/呼叫 ZALBB


    精华贴数 8
    个人空间 0
    技术积分 40298 (23)
    社区积分 18229 (107)
    注册日期 2001-10-15
    论坛徽章:129
          
          

    发表于 2004-9-27 00:09 
    恩,你中间这两段比较精辟。

    但我理解:ORACLE并不是为了效率才考虑意向锁,
    而是为了避免在执行DML操作时,可能与DDL会造成的表结构不一致才加的S锁。
    如:

    If a transaction obtains a row lock for a row, the transaction also acquires a table lock for the corresponding table. The table lock prevents conflicting DDL operations that would override data changes in a current transaction.

    file://server.920/a96524/c21cnsis.htm#2989

    实际上你说的和我思考的是一致的。
    你从锁的引入及应用延伸出发,理论讲解得清楚。

    而我只重点思考,ORACLE为什么要这样定义锁级别。
    如何根据应用来思考这些锁级别。


    但我目前所理解的SRX,就是:SRX--表结构共享锁+所有记录排它锁
    还不知道是不是对的?
    而且实际应用中,我还没想起什么情况下是会用上SRX。
    你若方便,请解释我这想法是不是对的。


    __________________
    对内,共匪什么都要,就是不要脸;对外,共匪什么都不要,就是要脸。
    只看该作者    顶部
    离线 jeffli73
    侠之大者


    精华贴数 2
    个人空间 133
    技术积分 10583 (145)
    社区积分 21 (8950)
    注册日期 2002-6-17
    论坛徽章:1
    授权会员     
          

    发表于 2004-9-28 01:00 
    我想如下的理解可能更本质一些

    "意向锁",实际上是在上层结点做出的某种标记,来表示在下级结点要加何种类型的锁.
    比如在ORACLE中,要修改一行,也就是要在行上加X锁,首先要在其上级,也就是表级做出表示,即加RX锁.
    这样做的好处是,以后不管是其它DML操作或是DDL操作,在检查是否有锁冲突时,就不需要逐行检查各记录的加锁情况了,而只需要检查表一级的加锁情况,所以我说其本质是要提高检查锁冲突的效率.
    另外,你在这里提出的所谓"表结构共享锁"是不正确的,DML锁不涉及表结构锁的问题.

    表上的5种锁的含义:
    RS(SS):是一种纯粹的意向锁,它表征事务要通过SELECT FOR UPDATE访问某些行;
    RX(SX):是一种纯粹的意向锁,它表征事务要通过 UPDATE/ DELETE/INSERT修改某些行;
    S:全表范围的共享锁,不需要在每行上做出标识;
    X:全表范围的排它锁,不需要在每行上做出标识;
    SRX(SSX):是意向锁RX与S锁的组合,它表征事务既对表加S锁,同时要修改个别行,即要在个别行上加X锁;(如果你使用ORACLE8,可以在一个表上建立一个自引用,如EMP表上的MGR引用EMPNO,删除一条记录,可以观察到SRX锁)

    在行上,ORALCE只有X锁,
    但由SELECT FOR UPDATE 获得的X锁在表级表征为RS锁,
    由INSERT/UPDATE/DELETE 获得的X锁在表级表征为RX锁,


    __________________
    安能摧眉折腰事权贵,使我不得开心颜天生我才必有用,千金散尽还复来个人BLOG: http://blog.china-pub.com/blog.asp?name=jefflee包括数据库、软件工程、电信及其它方面的个人感悟,如有兴趣,欢迎访问
    只看该作者    顶部
    离线 lutian
    PUB首席大叔


    精华贴数 0
    个人空间 0
    技术积分 550 (4251)
    社区积分 1905 (784)
    注册日期 2002-10-11
    论坛徽章:57
    生肖徽章2007版:虎2009新春纪念徽章生肖徽章2007版:猪   
          

    发表于 2004-9-28 09:29 
    谢谢分享!


    __________________
    后知后觉,不知不觉。
    只看该作者    顶部
    相关内容


    CopyRight 1999-2006 itpub.net All Right Reserved.
    北京皓辰网域网络信息技术有限公司. 版权所有
    E-mail:Webmaster@itpub.net
    网站律师 隐私政策 知识产权声明
    京ICP证:060528号 联系我们