查看: 84072|回复: 96

[精华] 我对ORACLE数据锁的一点体会

[复制链接]
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
跳转到指定楼层
1#
发表于 2004-9-24 17:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
该贴的部分内容是针对帖中带的附件(一位大侠关于锁的理解),提的理解/疑问,
大家在读此贴前,请先阅读该文。


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

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 语句无差别。

请拍砖。

oracle多粒度封锁机制研究(论坛).doc

139.5 KB, 下载次数: 5161

招聘 : 数据库管理员
论坛徽章:
21
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
2#
发表于 2004-9-26 00:17 | 只看该作者
1、我对文章中意向锁的理解,就是:对表的记录进行操作之前,先对表定义(包括表结构、约束等)
加了共享锁,这是为了避免对表的DDL操作。

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

这是我理解的意向锁。

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

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

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

anyway,

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
3#
发表于 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老师的做法,不过到时也可能有的朋友已经帮我写好了。

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
4#
 楼主| 发表于 2004-9-26 10:50 | 只看该作者
jeffli73,请看看我的问题:

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

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
5#
 楼主| 发表于 2004-9-26 11:02 | 只看该作者
最初由 grassbell 发布
[B]1、我对文章中意向锁的理解,就是:对表的记录进行操作之前,先对表定义(包括表结构、约束等)
加了共享锁,这是为了避免对表的DDL操作。

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

这是我理解的意向锁。

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

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

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

anyway, [/B]


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

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

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

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

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

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

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
6#
 楼主| 发表于 2004-9-26 11:10 | 只看该作者
要说清楚的是:共享锁,排它锁都体现在记录(数据)和表结构上,但由于记录是存储在
在表中的,脱离表结构来谈记录(数据)是无意义的,所以,我开头的文章里
没有单独的记录(数据)共享锁,而是要结合表结构,便这样理解这7个级别的锁。

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
7#
发表于 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说在他们准备在新出的书中选用,我想现在可能不便公开.

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
8#
 楼主| 发表于 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。
你若方便,请解释我这想法是不是对的。

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
9#
发表于 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锁,

使用道具 举报

回复
论坛徽章:
113
生肖徽章2007版:羊
日期:2011-10-11 10:20:29生肖徽章2007版:羊
日期:2011-10-11 10:20:29生肖徽章2007版:羊
日期:2011-10-11 10:20:29生肖徽章2007版:羊
日期:2011-10-11 10:20:29生肖徽章:猴
日期:2007-04-10 01:23:40生肖徽章:虎
日期:2011-10-11 10:20:29生肖徽章:羊
日期:2007-08-12 22:22:56生肖徽章:兔
日期:2007-08-15 17:25:14生肖徽章:虎
日期:2011-10-11 10:20:29生肖徽章:虎
日期:2007-09-24 07:24:16
10#
发表于 2004-9-28 09:29 | 只看该作者
谢谢分享!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表