文档章节

Oracle谨慎使用嵌套查询作为锁机制条件

Arthur126
 Arthur126
发布于 2016/07/12 10:08
字数 854
阅读 49
收藏 1

案例:Oracle 11g里写了一个存储过程,内容为执行update语句,更改表记录状态,目的是对表记录进行锁定。应用服务器集群调用同一个数据库的这个存储过程。最后发现,多个WebLogic实例都更新了同一条记录。锁机制失效。

进行代码测试:

数据初始化准备

create table tb_test_tab(
id number(10),
name varchar2(10),
statu varchar2(10)
);

truncate table tb_test_tab;
insert into tb_test_tab values (1001,'1','1');
insert into tb_test_tab values (1002,'2','1');
insert into tb_test_tab values (1003,'3','1');
insert into tb_test_tab values (1004,'4','1');
insert into tb_test_tab values (1005,'5','1');
insert into tb_test_tab values (1006,'6','1');
commit;

在plsql客户端开2个sql窗口,第一个窗口执行以下语句,不进行提交事务。

update  tb_test_tab t set t.name='343333',t.statu='2' where t.statu='1' and t.id=1001;

第二个窗口同时执行以下语句,提交事务。

update  tb_test_tab t set t.name='343333',t.statu='3' where t.statu='1' and t.id=1001;
commit;

此时第二个语句的commit处于等待状态,现在提交第一个窗口的事务,第二个事务也会立即提交。查看结果发现 t.id=1001记录的 t.statu值为2。说明表的锁机制成功!

现在换成嵌套语句作为更新条件进行执行更新处理,看下锁机制如何,操作步骤如下:

先初始化数据。

truncate table tb_test_tab;
insert into tb_test_tab values (1001,'1','1');
insert into tb_test_tab values (1002,'2','1');
insert into tb_test_tab values (1003,'3','1');
insert into tb_test_tab values (1004,'4','1');
insert into tb_test_tab values (1005,'5','1');
insert into tb_test_tab values (1006,'6','1');
commit;

同样在plsql客户端开2个sql窗口,第一个窗口执行以下语句,不进行提交事务。语句含义就是将statu='1'的记录升序后的前三条设置statu='2',name='22222'。

update tb_test_tab t
   set t.name = '22222', t.statu = '2'
 where t.id in (select id
                  from (select r.id from tb_test_tab r where r.statu='1' order by r.id)
                 where rownum <= 3);

第二个窗口同时执行以下语句,提交事务。

update tb_test_tab t
   set t.name = '33333', t.statu = '3'
 where t.id in (select id
                  from (select r.id from tb_test_tab r where r.statu='1' order by r.id)
                 where rownum <= 3);
commit;

此时第二个语句的commit处于等待状态,现在提交第一个窗口的事务,第二个事务也会立即提交。查看结果发现id升序后的前三条记录的 statu='3',name='33333'。 说明表的锁机制存在异常,至少不是之前我们想象的那样的结果(之前想象的结果应该是 statu='2',name='22222'。 第二个窗口执行的语句更新记录为0条)!  这个也许就是Oracle内部锁机制灵敏度不针对嵌套语句里面的结果集。故需要谨慎使用嵌套语句作为锁机制的限制条件。

如果想上面嵌套语句不变,同时想让锁机制起到效果,可以将嵌套语句里面的限制条件在最外层再写一遍即可。具体如下。第一个窗口改成:

update tb_test_tab t
   set t.name = '22222', t.statu = '2'
 where t.id in (select id
                  from (select r.id from tb_test_tab r where r.statu='1' order by r.id)
                 where rownum <= 3)
    and t.statu='1';

第二个窗口改成:

update tb_test_tab t
   set t.name = '33333', t.statu = '3'
 where t.id in (select id
                  from (select r.id from tb_test_tab r where r.statu='1' order by r.id)
                 where rownum <= 3)
    and t.statu='1';
commit;

© 著作权归作者所有

共有 人打赏支持
Arthur126
粉丝 1
博文 33
码字总数 17900
作品 0
徐汇
高级程序员
私信 提问
Oracle sql优化必知——表的访问

《访问数据的方法》 访问表中的数据有两种:1、直接访问表 2、先访问索引,再回表 1、直接访问表的两种方法: ①、全表扫描 全表扫描是指Oracle在访问目标表的数据时,会从该表所占用的第一个...

一个笨小孩
2017/08/03
0
0
MySQL事务原理&实战【官方精译】

事务隔离级别 事务隔离是数据库处理的基础之一。隔离是I中的首字母 ACID ; 隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡进行微调的设置...

sunsky303
2017/12/27
0
0
优化SQL查询:如何写出高性能SQL语句

2、 统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。 3、 不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A...

Oscarfff
2015/10/28
0
0
每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

本周为大家送出的书是《Oracle 12 c PL(SQL)程序设计终极指南》,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著。 内容简介: 《Oracle 12c PL/SQL程序设计终极指南》志在打造PL/SQL领...

zting科技
2017/12/11
0
0
ORACLE的锁机制 - blue - 博客园

设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据的一致性和准确性。Oracle数据库封锁方式有三种:共享封锁,独占封锁,共享更新封锁 Oracle RDBMS的封锁类型可分为如下...

低至一折起
2017/12/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Windows 10 设置 Java 环境变量

首先你需要在我的电脑中打开,找到环境变量属性。 找到环境变量属性 找到环境变量属性后单击将会看到下面的设置界面。 在这个界面中设置高级系统设置。 环境变量 在弹出的界面中选择设置环境...

honeymose
58分钟前
1
0
用any-loader封装jQuery的XHR —— 随便写着玩系列

哎,都说没人用JQuery啦,叫你别写这个。 其实我也是好高骛远使用过npm上某个和某个很出名的XHR库,嗯,认识我的人都知道我喜欢喷JQ,以前天天喷,见面第一句,你还用JQ,赶紧丢了吧。但我也...

曾建凯
今天
5
0
聊聊storm的AggregateProcessor的execute及finishBatch方法

序 本文主要研究一下storm的AggregateProcessor的execute及finishBatch方法 实例 TridentTopology topology = new TridentTopology(); topology.newStream("spout1", spout......

go4it
今天
4
0
大数据教程(7.5)hadoop中内置rpc框架的使用教程

博主上一篇博客分享了hadoop客户端java API的使用,本章节带领小伙伴们一起来体验下hadoop的内置rpc框架。首先,由于hadoop的内置rpc框架的设计目的是为了内部的组件提供rpc访问的功能,并不...

em_aaron
今天
5
0
CentOS7+git+github创建Python开发环境

1.准备CentOS7 (1)下载VMware Workstation https://pan.baidu.com/s/1miFU8mk (2)下载CentOS7镜像 https://mirrors.aliyun.com/centos/ (3)安装CentOS7系统 http://blog.51cto.com/fengyuns......

枫叶云
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部