文档章节

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
优化SQL查询:如何写出高性能SQL语句

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

Oscarfff
2015/10/28
0
0
MySQL事务原理&实战【官方精译】

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

sunsky303
2017/12/27
0
0
oracle存储过程 调优 基础篇

1、如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用“databsevv.dbo.tablename”,因为spdepends不能显示出该SP所使用的跨库table或view,不方便校验...

娲城小将
2014/11/11
0
0
关于MySQL的知识点与面试常见问题都在这里

摘要: Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide 书籍推荐 《高性能MySQL : 第3版》 文字教程推荐 MySQL ...

传授知识的天使
06/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

C++ std::thread

C++11提供了std::thread类来表示一个多线程对象。 1,首先介绍一下std::this_thread命名空间: (1)std::this_thread::get_id():返回当前线程id (2)std::this_thread::yield():用户接口...

yepanl
53分钟前
2
0
Nignx缓存文件与动态文件自动均衡的配置

下面这段nginx的配置脚本的作用是,自动判断是否存在缓存文件,如果有优先输出缓存文件,不经过php,如果没有,则回到php去处理,同时生成缓存文件。 PHP框架是ThinkPHP,最后一个rewrite有关...

swingcoder
57分钟前
1
0
20180920 usermod命令与用户密码管理

命令 usermod usermod 命令的选项和 useradd 差不多。 一个用户可以属于多个组,但是gid只有一个;除了gid,其他的组(groups)叫做扩展组。 usermod -u 1010 username # 更改用户idusermod ...

野雪球
58分钟前
1
0
Java网络编程基础

1. 简单了解网络通信协议TCP/IP网络模型相关名词 应用层(HTTP,FTP,DNS等) 传输层(TCP,UDP) 网络层(IP,ICMP等) 链路层(驱动程序,接口等) 链路层:用于定义物理传输通道,通常是对...

江左煤郎
今天
1
0
使用xtrabackup完成远程备份

转载收藏,以防丢失 需求 Can I backup remote databases from my local server02-27-2013, 06:17 AMHi, I am using mysqldump so far for taking daily backups of my Production datab......

阿dai
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部