Select...for update 语句是我们经常使用手工加锁语句。通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作。同时,在多版本一致读机制的支持下,select语句也不会被其他类型语句所妨碍。

借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作。

加锁范围子句:

在select ....for update 之后,可以使用of子句选择对select的特定数据表进行加锁操作。默认情况下,不使用of子句表示在select所有的数据表中加锁。

// 采用默认格式for update------select * from emp where  rownum<2 for udpate;

此时,我们观察v$lock和v$locked_object视图,可以看到锁信息。

// 事务信息视图-------select addr ,xidusn,xidslot,sdsqn from v$transaction;

//锁对象信息

SQL> select xidusn,xidslot,xidsqn,object_id,session_id, oracle_username from v$locked_object;

从上面的情况看,默认情况下的for update语句,效果相当于启动了一个会话级别的事务,在对应的数据表(select所涉及的所有数据表)上加入一个数据表级共享锁(TM,lmode=3)。同时,在对应的数据行中加入独占锁(TX,lmode=6)。

根据我们以前的知识,如果此时有另一个会话视图获取对应数据行的独占权限(无论是用update/delete还是另一个for update),都会以block而告终。

for update子句的默认行为就是自动启动一个事务,借助事务的锁机制将数据进行锁定。

Of子句是配合for update语句使用的一个范围说明标记。从官方的语法结构看,后面可以跟一个或者多个数据列列表。这种语法场景常常使用在进行连接查询的select中,对其中一张数据表数据进行锁定。

SQL> select empno,ename,job,mgr,sal from emp,dept where emp.deptno=dept.deptno and empno=7369 for update of emp.empno;

当我们进行for update的操作时,与普通select存在很大不同。一般select是不需要考虑数据是否被锁定,最多根据多版本一致读的特性读取之前的版本。加入for update之后,Oracle就要求启动一个新事务,尝试对数据进行加锁。如果当前已经被加锁,默认的行为必然是block等待。

使用nowait子句的作用就是避免进行等待,当发现请求加锁资源被锁定未释放的时候,直接报错返回。

//变换session,进行执行。

SQL> select * from emp for update nowait;

select * from emp for update nowait

ORA-00054:资源正忙,但指定以NOWAIT方式获取资源,或者超时失效

对应的还有就是wait子句,也就是默认的for update行为。一旦发现对应资源被锁定,就等待blocking,直到资源被释放或者用户强制终止命令。

对wait子句还存在一个数据参数位,表示当出现blocking等待的时候最多等待多长时间。单位是秒级别。

//接上面的案例

SQL> select * from emp for update wait 3;

select * from emp for update wait 3

ORA-30006:资源已被占用;执行操作时出现WAIT超时

Skip locked参数是最新引入到for update语句中的一个参数。简单的说,就是在对数据行进行加锁操作时,如果发现数据行被锁定,就跳过处理。这样for update就只针对未加锁的数据行进行处理加锁。

//session1中,对一部分数据加锁;

SQL> select * from emp where rownum<4 for update;

对for update的使用

在日常中,我们对for update的使用还是比较普遍的,特别是在如pl/sql developer中手工修改数据。此时只是觉得方便,而对for update真正的含义缺乏理解。

For update是Oracle提供的手工提高锁级别和范围的特例语句。Oracle的锁机制是目前各类型数据库锁机制中比较优秀的。所以,Oracle认为一般不需要用户和应用直接进行锁的控制和提升。甚至认为死锁这类锁相关问题的出现场景,大都与手工提升锁有关。所以,Oracle并不推荐使用for update作为日常开发使用。而且,在平时开发和运维中,使用了for update却忘记提交,会引起很多锁表故障。

 

那么,什么时候需要使用for update?就是那些需要业务层面数据独占时,可以考虑使用for update。场景上,比如火车票订票,在屏幕上显示邮票,而真正进行出票时,需要重新确定一下这个数据没有被其他客户端修改。所以,在这个确认过程中,可以使用for update。这是统一的解决方案方案问题,需要前期有所准备


转载于:https://blog.51cto.com/qyweiyy/1791070

加锁查询 FOR UPDATE 解决表格查询极慢的问题相关推荐

  1. php redis 分页查询,redis如何解决分页查询

    我们都知道,通过缓存查询的结果,可以极大的提升系统的服务能力,以及降低底层服务或者是数据库的压力.对于有分页条件的缓存,我们也可以按照不同的分页条件来缓存多个key. 基于SortedSet的分页查询 ...

  2. oracle锁表查询_专业解决 MySQL 查询速度慢与性能差

    Java识堂,一个高原创,高收藏,有干货的微信公众号,一起成长,一起进步,欢迎关注 什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS: QueriesPerSe ...

  3. dsum 解决 access数据库中 update的子查询问题

    在access中,update语句不能有子查询的,如不允许如下语句出现: UPDATE tblA SET lngID=       (SELECT lngID FROM tblB WHERE strN ...

  4. Hibernate执行Update操作之后查询跟新的语句出错

    转自http://zxyqingkong.diandian.com/post/2012-05-26/21649154,内容还不是很清楚,只是转载作为暂存,以后深入研读,所有权利归原作者所有. Prev ...

  5. mysql表格查询方法

    笛卡尔积 交叉连接(CROSS JOIN):有两种,显式的和隐式的2种,一般用来返回连接表的笛卡尔积. 笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积. 例如,有 A ...

  6. 使用插桩技术解决慢查询测试问题

    原文由zlulu发表于TesterHome社区,原文链接 缘起 前段时间,我负责测试的系统在生产环境运行出现问题.该系统对于响应时间要求较高,问题发生的时候并发很高,出现大量请求超时,超时请求比例随时 ...

  7. mysql 查询rowno_C# Mysql 查询 Rownum的解决方法

    C# Mysql 查询 Rownum的解决方法,需要的朋友可以参考一下 Sql: 代码如下: SELECT @rownum:=@rownum+1 AS rownum, a.order_id , cas ...

  8. 解决PLSQL 查询后显示中文为问号(???)问题

    解决PLSQL 查询后显示中文为问号(???)问题 参考文章: (1)解决PLSQL 查询后显示中文为问号(???)问题 (2)https://www.cnblogs.com/wqkeep/p/120 ...

  9. 数据库分库分表和带来的唯一ID、分页查询问题的解决

    数据库分库分表和带来的唯一ID.分页查询问题的解决 参考文章: (1)数据库分库分表和带来的唯一ID.分页查询问题的解决 (2)https://www.cnblogs.com/hanzhong/p/1 ...

最新文章

  1. 醉没醉,带上智能手机走两步就知道
  2. Java程序员从笨鸟到菜鸟之(四十四)细谈struts2(七)数据类型转换详解
  3. 漫说模板方法模式---学生时代的烦恼
  4. 主动防御型杀毒软件的技术探讨
  5. python init函数可以外部调用么,如何从python类中调用外部函数
  6. 现在有一个整数数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数...
  7. python 爬取大乐透开奖结果
  8. 设计自己的ImageLoader图片加载框架
  9. E: 无法打开锁文件 /var/lib/dpkg/lock-frontend - open (2: 没有那个文件或目录)
  10. ArcGis如何插入图片_如何在CAD图纸中以OLE形式插入图片?
  11. 【转载】网络工程师行业的岗位认知
  12. 微信公众号推送html文件,如何利用微信公众号推送教学资源?
  13. 微信小程序开发 uniapp【bug修复】点击事件 传值 数据结构错误 $orig
  14. 英文 SCI 论文写作常用句式(保持更新)
  15. Android按键音
  16. 紫色店铺商家信息后台管理模板
  17. 电影《寒战1》中的管理知识
  18. 浏览器中新开标签页(Tab)
  19. linux驱动之一、LED驱动(驱动代码小结附:github代码链接)
  20. Roller 工程的构建

热门文章

  1. Scala数值类型转换
  2. PHP数组函数总结与使用
  3. PostCSS理解与运用
  4. POJ 1190 生日蛋糕 【DFS + 极限剪枝】
  5. cookie的路径和域
  6. iOS-获取子视图父控制器
  7. ZooKeeper的配置文件优化性能(转)
  8. python_day9 进程池
  9. mybatis基础,mybatis配置文件核心组件typeHandler元素
  10. 【leetcode】Balanced Binary Tree(middle)