楼主: yangtingkun

[精华] 在Oracle中如何实现读锁

[复制链接]
论坛徽章:
20
参与2007年甲骨文全球大会(中国上海)纪念
日期:2007-08-06 15:19:002012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:52马上有车
日期: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:09:52
41#
发表于 2008-6-10 14:55 | 只看该作者
原帖由 yangtingkun 于 2008-6-10 14:24 发表



在这篇文章的开头部分我就写了



因此这篇文章并没有什么明确的需求,只是单纯为了实现读锁的功能,至于读锁有什么意义,我在日常使用中并没有碰到需要读锁的情况,但是并不代表一定没有意义。

你给出的方法,我只是说明这种方法会破坏事务的原子性,如果采用这种方法,对这张表的访问就无法放到事务当中。

另外,你的方法其实没有必要提交的,我的第一种方法就与你的方法类似,但是并没有提交,因此事务的原子性还可以保证。


不用把更新控制表的部份看成是事务一部份,真正的业务逻辑在第二部份,第二部份可以是一个单独的查询,或者是一个封装的事务,对于业务事务的原子性一点都没有破坏的。

事务的原子性这种东西,看你以什么样的角度去看?还有事务设计是否合理?这都是我们应该去考虑的问题。

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
42#
 楼主| 发表于 2008-6-10 15:17 | 只看该作者
问题是采用这种方法一般需要将UPDATE和SELECT封装在一起,否则无法保证读表之前对控制表进行更新。

那么这种实现方法只能以一个独立事务的方式实现读表,或者包括读表在内的部分写死的逻辑。

普通用户的事务如果执行了一半,调用这个读表的方法,当前的事务就被迫提交

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
25
生肖徽章2007版:龙
日期:2008-05-06 11:07:48咸鸭蛋
日期:2011-10-19 10:09:12ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24
43#
发表于 2008-6-10 16:05 | 只看该作者
读锁度于oracle的意义到底有多大。还是老杨只是研究研究。不过研究的结果让我很是佩服啊。呵呵。多谢!

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
44#
发表于 2008-6-10 16:32 | 只看该作者
原帖由 zhaolinjnu 于 2008-6-9 16:36 发表
首先不论此需求的合理性,对于此需求的实现,这里有另外一种思路?

首先创建另外一张表,插入一条类似下面这样的记录:
insert into select_ctl(table_name,lock_start,lock_end,status) values('TEST',SYSDATE,SYSDATE,0);
这张表可以称为对Test表的select查询访问控制表,status有两个状态:0 未锁定;1 锁定中

当要进行select查询时:
1.更新控制表select_ctl中的记录 update select_ctl set lock_start=sysdate,lock_end=null,status=1 where table_name='TEST' and status=0;
commit;
2.判断更新的结果集行数,如果为1,则进行相要的select查询(如果为0,则在应用层等待一下,再次返回到第一步中的更新):
    比如说: select * from test;
3.查询完成后,更新控制表select_ctl,以便其它的会话可以进行查询
  update select_ctl set lock_end=sysdate,status=0 where table_name='TEST' and status=1;
  commit;


如果这类的需求一定要处理,并且采用此设计实现,可以对select_ctl表中的记录进行监控。

看似简单其实问题挺多
除了杨大师说的事务问题,还有个问题:
“如果为0,则在应用层等待一下,再次返回到第一步中的更新”
如何调度?等待一下是多久?如果第n次也没等到怎么办?

使用道具 举报

回复
论坛徽章:
20
参与2007年甲骨文全球大会(中国上海)纪念
日期:2007-08-06 15:19:002012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:52马上有车
日期: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:09:52
45#
发表于 2008-6-10 17:27 | 只看该作者
为什么设计成这样?第一是设想的,这个需求所要进行的操作并发度本来就不怎么高!所以不会出现等很久的情况。如何设置等待多长时间的问题,这个要根据应用的特点来确定。如果并发度很高,在数据库中实现一个读排它性锁,是有很大问题的。

不过,为了解决上面的问题,还是有方法的:
那就是要加入队列机制,直接用ORACLE的行锁功能实现就行了,在第一步更新时去掉status=0的条件
去掉第一步的commit,,,也不用判断影响的结果集了把整个操作包装成事务就行了!第三步的status=1的条件也可以去掉!

本帖只是提供一种方法,任何一种方法都有优点与缺点。欢迎大家继续讨论。不要局限于ORACLE为我们提供了什么?
我们自己也可以去设计一些功能。

使用道具 举报

回复
论坛徽章:
33
劳斯莱斯
日期:2013-08-08 14:01:23三菱
日期:2013-09-28 10:16:06一汽
日期:2013-11-19 17:01:11凯迪拉克
日期:2013-12-07 17:11:282014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02itpub13周年纪念徽章
日期:2014-09-27 14:20:21itpub13周年纪念徽章
日期:2014-10-08 15:13:38懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
46#
发表于 2008-6-11 08:13 | 只看该作者
都是高手,学习

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
47#
发表于 2008-6-11 08:48 | 只看该作者
原帖由 zhaolinjnu 于 2008-6-10 17:27 发表
为什么设计成这样?第一是设想的,这个需求所要进行的操作并发度本来就不怎么高!所以不会出现等很久的情况。如何设置等待多长时间的问题,这个要根据应用的特点来确定。如果并发度很高,在数据库中实现一个读排它性锁,是有很大问题的。

不过,为了解决上面的问题,还是有方法的:
那就是要加入队列机制,直接用ORACLE的行锁功能实现就行了,在第一步更新时去掉status=0的条件
去掉第一步的commit,,,也不用判断影响的结果集了把整个操作包装成事务就行了!第三步的status=1的条件也可以去掉!

本帖只是提供一种方法,任何一种方法都有优点与缺点。欢迎大家继续讨论。不要局限于ORACLE为我们提供了什么?
我们自己也可以去设计一些功能。

问题当然都是能解决的
归根到底就是引入一个独占资源就是了
其实这一部分放应用层实现也很简单,如利用java的synchronized,wait,notify

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
48#
 楼主| 发表于 2008-6-11 10:06 | 只看该作者
原帖由 anlinew 于 2008-6-11 08:48 发表

问题当然都是能解决的
归根到底就是引入一个独占资源就是了
其实这一部分放应用层实现也很简单,如利用java的synchronized,wait,notify


无论是在JAVA层实现,还是丹臣所说的那样封装起来,都有一个问题,只能保证通过应用的访问或者通过调用封装的接口访问时可以实现。
对于用户的其他访问方式,比如sqlplus直接查询无能为力。
当然这并不一定是坏事,关键看具体的需求如何

使用道具 举报

回复
论坛徽章:
26
2010年世界杯参赛球队:葡萄牙
日期:2012-09-20 14:59:08密尔沃基雄鹿
日期:2012-03-20 16:57:19海蓝宝石
日期:2012-07-26 23:23:38奥运会纪念徽章:乒乓球
日期:2012-09-07 16:24:16奥运会纪念徽章:足球
日期:2012-09-07 16:24:16马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24灰彻蛋
日期:2012-12-31 12:03:56蜘蛛蛋
日期:2012-11-29 17:20:08
49#
发表于 2008-6-19 22:49 | 只看该作者
学习

使用道具 举报

回复
论坛徽章:
11
数据库板块每日发贴之星
日期:2007-10-10 01:04:092010新春纪念徽章
日期:2010-01-04 08:33:08祖国60周年纪念徽章
日期:2009-10-09 08:28:00生肖徽章2007版:马
日期:2009-04-12 17:19:242009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:猪
日期:2008-05-06 11:10:422008新春纪念徽章
日期:2008-02-13 12:43:03生肖徽章2007版:鼠
日期:2008-01-02 17:35:53授权会员
日期:2007-11-02 16:47:52ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44
50#
发表于 2008-6-19 23:40 | 只看该作者
学习

使用道具 举报

回复

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

本版积分规则 发表回复

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