关闭

【Oracle】从select for update开始

标签: 数据库
1053人阅读 评论(0) 收藏 举报
分类:

从select for update开始

开发多用户、数据库驱动的应用时,最大的难点之一时:一方面要力争取得最大限度地并发访问,与此同时还要确保每个用户以一致的方式读取和修改数据。为此就有了锁定(locking)机制。

AE锁是一个版本锁,这是oracle 11g新增的。
TX(事务处理锁):修改数据的事务在执行期间会获得这种锁。
TM(DML队列)锁和DDL锁:在你修改一个对象的内容(对应TM锁)或对象本身(对应DDL锁)时,这些锁可以确保对象的结构不被修改。
闩(latch)和Mutex:这是Oracle的内部锁,用来协调对其共享数据结构的访问。

数据库中有5条常见的DML语句可能会阻塞,具体是:INSERT、UPDATE、DELETE、MERGE和SELECT FOR UPDATE。对于一个阻塞的SELECT FOR UPDATE,解决的方案很简单:只需要增加NOWAIT子句,它就不会阻塞了。
下面我们看看测试用例。

User1连接数据库。

C:\Users\Administrator>sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on 星期日 828 20:27:46 2016

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create table test(name varchar2(20))
  2  ;

表已创建。

SQL> insert into test values('testname');

已创建 1 行。

SQL> commit;

SQL> update test set name='nameupdate';

User1在如上的操作中,创建了表,对表进行了insert操作,提交(commit)事务。对表进行了update操作(并没有提交事务,此时,test表的这一行数据被锁住了)

User2连接数据库。再打开一个sqlplus.

C:\Users\Administrator>sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on 星期日 828 20:31:04 2016

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> select name from test for update;

发现,由于前一个session开始的事务没有结束,此时再开启一个事务后,尝试使用for update对test表进行锁定,但是数据库处于挂起状态。
User1回滚后,锁被释放。

SQL> rollback;

User2得到结果

NAME
--------------------
testname

User1继续

SQL> update test set name='nameupdate';

User2继续,增加nowait,则立即返回了错误。

SQL> select name from test for update nowait;
select name from test for update nowait
*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效

而如果我们想查询的数据正在被修改,那么不会产生脏读(脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的)的情况。

SQL> select name from  test where name='testname' for update nowait;
select name from  test where name='testname' for update nowait
                  *
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效

for update nowait这种锁,称作悲观锁。因为我们怀疑数据会被修改,所以使用它,如果数据正在被修改,那我们选择(select)该数据时立马能知道结果,如果某条数据正在被修改,那么会得到ORA-00054的错误,如果修改已提交,那么查不到老数据。(参考[1])


参考资料
(1)Oracle_Database_9i10g11g编程艺术深入数据库体系结构第2版181页,锁定问题,6.2.2悲观锁定

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Select For update语句浅析

Select …forupdate语句是我们经常使用手工加锁语句。通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作。同时,在多版本一致读机制的支持下,select语句也不...
  • liqfyiyi
  • liqfyiyi
  • 2012-09-05 21:34
  • 143211

oracle行锁 select for update

问题是,如果两个人同时查询到了一条数据,第二个的修改就会造成第一个人获取失效。为了避免这种情况的发生,我们使用了select for update对获取到的行进行了加锁。下面简单介绍一下select ...
  • zdwzzu2006
  • zdwzzu2006
  • 2016-01-09 22:41
  • 5227

Oracle中select ... for update的用法

语法: SELECT... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED]; 其中OF 子句用于指定即将更新的列,即锁定行上的特...
  • nchu2020
  • nchu2020
  • 2016-08-25 10:10
  • 561

oracle for update of和for update区别

对比区别:   select * from TTable1 for update 锁定表的所有行,只能读不能写   2  select * from TTable1 where pkid = 1 ...
  • czy2001win
  • czy2001win
  • 2016-08-16 06:25
  • 4879

Oracle中使用pl/sql,查询结果可以直接修改sql语句-for update

Oracle中使用pl/sql,查询结果可以直接修改sql语句-for update 有时需要使用pl/sql查询语句,并直接就该条语句进行修改,只要在搜索语句末尾加一个 for update 语...
  • bestcxx
  • bestcxx
  • 2015-10-30 17:23
  • 3661

oracle行锁 select for update

问题是,如果两个人同时查询到了一条数据,第二个的修改就会造成第一个人获取失效。为了避免这种情况的发生,我们使用了select for update对获取到的行进行了加锁。下面简单介绍一下select ...
  • u013310119
  • u013310119
  • 2016-07-13 17:17
  • 2972

oracle update 实现多行多列更新

在网上看到的,记录下,实现多行多列更新 update table1 r set (r.city,r.COUNTY,r.CELL_NAME,r.CELL_UK)  =  ( select  ...
  • windhawk777
  • windhawk777
  • 2016-08-12 12:45
  • 3065

select...for update使用方法

作用: select for update 是为了在查询时,避免其他用户以该表进行插入,修改或删除等操作,造成表的不一致性.   给你举几个例子: select * from t for up...
  • zwl156135995
  • zwl156135995
  • 2016-05-18 17:42
  • 6291

Select For Update行级锁定

Oracle的Select For Update语句可以实现在读取数据后马上锁定相关资源,防止被其他session修改数据的目的。也就是我们常常谈到的“悲观锁定”(现实应用开发中,使用悲观锁定的情况...
  • zhangshufa
  • zhangshufa
  • 2011-10-01 22:36
  • 19298

select语句for update作用

Select…For Update语句的语法与select语句相同,只是在select语句的后面加FOR UPDATE [NOWAIT]子句。 该语句用来锁定特定的行(如果有where子句,就是...
  • kb5706
  • kb5706
  • 2012-04-23 09:55
  • 4376
    个人资料
    • 访问:54659次
    • 积分:919
    • 等级:
    • 排名:千里之外
    • 原创:38篇
    • 转载:11篇
    • 译文:1篇
    • 评论:10条
    文章分类
    最新评论