Oracle中的锁

2023-11-14

     Oracle数据库支持多个用户同时与数据库进行交互,每个用户都可以同时运行自己的事务,从而也需要对并发访问进行控制。Oracle也是用“锁”的机制来防止各个事务之间的相互影响,对并发访问进行控制的,保证数据的一致性和完整性。当一个事务或操作企图防止另一个事务对其操作的对象产生影响时,该事务或操作就对该对象进行锁定,其他事务就只能在该事务释放锁之后才能操作该对象。

     在大多数情况下,锁对于开发人员来说是透明的,不用显式地加锁,即不用指定锁的分类、级别、类型或模式。如,当更改记录时,Oracle会自动地对相关的记录加相应的锁;当执行一个PL/SQL过程时,该过程就会自动地处于被锁定的状态,允许其他用户执行它,但不允许其他用户采用任何方式更改该过程。当然,Oracle也允许用户使用Lock Table语句显式地对被锁定的对象加指定模式的锁。

     锁有2种最基本、最简单的类型:排他锁(eXclusive lock,即X锁)、共享锁(Share lock,即S锁)。这两种锁及其锁定的示意图如下图所示。该图中显式了不同的锁的作用,以及相互之间的相容规则。

  

                                 

    排他锁又称为写锁。如果事务T在数据库对象A上加了X锁,则只允许T读取、更改A。其他任何事务Ti都既不能对A加S锁也不能加X锁,直到T释放A上的X锁为止。这就保证了其他事务Ti在事务T释放A上的X锁之前,不能再读取、更改、使用A,即保护A不被同时地读、写。

    共享锁又称为读锁。如果事务T在数据库对象A上加了S锁,则只允许T读取A但不能更改A。其他任何事务Ti都只能对A加S锁而不能加X锁,直到T释放A上的S锁为止。这就保证了其他事务Ti在事务T释放A上的S锁之前,只能读取A但不能更改A,即保护A不被同时地写。

锁除了对操作进行限制外,锁对锁也进行限制,排他锁与共享锁的相容规则如表所示。

                                      

                                 

              

   

一、锁定的粒度与意向锁

    锁定对象的大小被称为锁定的粒度(granularity)。锁定对象可以是逻辑单元(如数据库、表、记录、列、索引等),也可以是物理单元(如数据页、索引页等)。

锁定的粒度与系统的并发度和并发控制的开销密切相关。一般地,锁定的粒度越大,需要锁定的对象就越少,可选择性就越小,并发度就越小,开销就越小;反之,锁定的粒度越小,需要锁定的对象就越多,可选择性就越大,并发度就越大,开销就越大。

    例如,如果锁定的粒度是表,事务T1需要操作表A中的记录r1,则T1必须对包含记录r1的表A加锁。在T1对A加锁之后,事务T2需要操作表A中的记录r2,因此就需要对表A加锁,但此时因为T1已经在表A上加了锁,所以T2的加锁就会失败,就被迫等待,直到T1释放锁为止,事务T1和T2就不能并发执行了;如果锁定的粒度是记录,则事务T1可以对表A中的记录r1加锁,同时事务T2也可以对表A中的记录r2加锁,所以事务T1和T2就可以并发执行了,并发度就增大了,但维护这个并发度就需要更多的开销了。

 

1、多粒度锁定与多粒度树

    如果在一个数据库管理系统中,同时支持多种锁定粒度供事务选择,这种锁定方法就被称为多粒度锁定(multiple granularity locking)。

    如下图所示是一个四级的多粒度树。该树的根节点是数据库,表示最大的粒度;页节点是列,表示最小的粒度。

                      

 从前面的例子可知,选择锁定粒度时应该同时考虑并发度与开销两个因素。以求最优的效果。一般地,需要处理大量记录的事务可以以表为锁定粒度;需要处理多个表中的大量记录的事务可以以数据库为锁定粒度;而只需要处理某个表中少量记录的事务,则可以以记录为锁定粒度。

    多粒度锁定协议是指,允许对多粒度树中的节点单独地加锁,另外,对一个节点加锁还意味着对这个节点的各级子节点也加同样的锁。   

    因此,可以用两种方法对多粒度树中的节点加锁:显式锁定、隐式锁定。显式锁定是在事务中明确指定要加在节点上的锁;隐式锁定是由于在其上级节点中加显式锁时而使该节点获得的锁。

在多粒度锁定中,显式锁定与隐式锁定的作用与相容规则都是一样的。因此,当系统检查锁定的冲突时,不仅要检查显式锁定还要检查隐式锁定。

    一般地,当对一个节点加锁时,系统第一要检查在该节点上有无显式锁定与之冲突;第二要检查其所有上级节点有无显式锁定与之冲突,以便查看在该节点上加该显式锁定,是否会与从上级节点获得的隐式锁定有冲突;第三要检查所有下级节点有无显式锁定与之冲突,以便查看在该节点上加该显式锁定,是否会使下级节点从该节点获得的隐式锁定与其显式锁定有冲突。

    这种检查锁定冲突的方法的效率很低,所以引进了意向锁(Intended lock)的概念。

 

2、意向锁

    意向锁的含义是,如果对一个节点加某种意向锁,则会对该节点的各级下级节点加这种锁;如果对一个节点加某种锁,则必须先对该节点的各级上级节点加这种意向锁。

例如,对记录r1加锁时,必须先对它所在的表A加意向锁。于是,事务T1对表A加X锁时,系统只需要检查根节点数据库D和表A是否已经加了不相容的锁,而不再需要检查表A中每个记录是否加了X锁。

有如下几种意向锁。

    一、IS锁(Intended Share lock,意向共享锁)

    如果对一个节点加IS锁,则表示对它的所有下级节点有加S锁的意向;如果对一个节点加S锁,则必须先对该节点的各级上级节点加IS锁。

    二、IX锁(Intended eXclusive lock,意向排他锁)

    如果对一个节点加IX锁,则表示对它的所有下级节点有加X锁的意向;如果对一个节点加X锁,则必须先对该节点的各级上级节点加IX锁。

    三、SIX锁(Share Intended eXclusive lock,共享意向排他锁)

    如果对一个节点加SIX锁,则表示对它加S锁,然后再加IX锁,即SIX=S+IX。例如,如果事务T对表A加SIX锁,则表示事务T要读取整个表(S锁的作用),同时还会更新某些记录(IX锁的作用)。

包括意向锁的各种锁之间的相容规则如表所示。

          

例如,当事务T对表A保持的锁是S锁时,事务Ti不可以获得对表A的IX锁,但可以获得对A的IS锁。所以S锁与IX锁的强度相当,但比IS锁的强度要强。

    同上理,可以逐个地推导出这些锁的强度关系,如图所示。图中上面的锁比下面的锁的强度要强,同级的锁强度相当。一个事务在申请锁定时以强锁代替弱锁是安全的(但会降低并发度),反之则不然。申请锁定时应该按自上而下的次序进行,释放锁定时则应该按自下而上的次序进行。

具有意向锁的多粒度锁定方法能提高系统的并发度,减少加锁和解锁的开销,已经在实际DBMS中得到应用,如Oracle数据库。

 

二、锁的分类

    Oracle主要有2种锁:DDL锁(字典锁)、DML锁(数据锁)。

1 DDL

    当用户发布DDL(Data Definition Language)语句时会对涉及的对象加DDL锁。由于DDL语句会更改数据字典,所以该锁也被称为字典锁。

    DDL锁能防止在用DML语句操作数据库表时,对表进行删除,或对表的结构进行更改。

    对于DDL锁,要注意的是:

    $$ DDL锁只锁定DDL操作所涉及的对象,而不会锁定数据字典中的所有对象。

    $$ DDL锁由Oracle自动加锁和释放。不能显式地给对象加DDL锁,即没有加DDL锁的语句。

    $$ 在过程中引用的对象,在过程编译结束之前不能被改变或删除,即不能被加排他DDL锁。

    DDL锁的类型与特征如表所示。

   

      DDL锁很少会在系统里引起争用,因为它们的保持时间都非常短暂。但DDL锁的存在却不容忽视,尤其是在申请排他DDL锁时。

2、DML

当用户发布DML(Data Manipulation Language)语句(如insert、update、delete)时会对涉及的对象加DML锁。由于DML语句涉及的是数据操作,所以该锁也被称为数据锁。

DML锁能防止多个事务并发访问数据时,对数据的一致性和完整性的破坏。

根据锁定的粒度和意向,DML锁有几种模式。在执行Lock Table语句或执行不同的DML语句时会加不同模式的DML锁。当一个事务在一个表上加了某种模式的DML锁之后,另一个事务在该表上所能执行的DML操作会受到限制,如下表所示。其中有的锁模式有2个名称,这是因为不同的Oracle版本在提到它们时使用了不同的表示方法。

三、死锁现象及其解决

    死锁是一种比较严重的、特殊的锁争用类型。在这种锁争用中,两个或两个以上的用户正在等待对方锁定的资源。因此,如果不进行某种干预,任意一个事务都无法完成。

假设当前有两个会话,分别执行的事务如图所示。显然这两个会话之间由于互相锁定了对方所需要锁定的对象,所以发生了死锁。

    “提示”Oracle提供了有效的死锁检测机制,周期性地(通常只有几秒钟)诊断系统中有无死锁,并提示用户。

当Oracle检测到死锁后,会在预警文件和跟踪文件中记录下死锁的信息,在跟踪文件中详细地记录了检测到死锁的时间、被死锁的语句、阻塞者会话、等待者会话、操作系统用户的信息(如用户名、用户所在的计算机、用户使用的应用程序)等有助于确定死锁及其处理方法的信息。

即使Oracle为会话A提示了检测到死锁的信息,并且回退了会话A的第2个update语句,但会话A仍然在第1个update语句上保持着锁,并阻塞了会话B的第2个update语句.

    当出现检测到死锁的信息后,用户自己(或DBA通知相应的用户)执行commit语句或rollback语句,使事务结束,释放所加的锁。还可以使用 ALTER SYSTEM KILL SESSION 'sid, serial#' 语句来杀死会话,强行解决锁争用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle中的锁 的相关文章

  • 从 oracle 中为每个组选择最新行

    我在留言簿中有一张包含用户评论的表格 列有 id user id 标题 评论 时间戳 我需要为每个用户选择最新行 我尝试使用 group by 执行此操作 但没有管理它 因为我无法在按 user id 分组的同一查询中选择任何其他内容 SE
  • SQL*Loader - 如何忽略具有特定字符的某些行

    如果我有一个以下格式的 CSV 文件 fd sdf dsfds dsfd fd asdf dsfds dsfd fd sdf rdsfds dsfd fdd sdf dsfds fdsfd fd sdf dsfds dsfd fd sdf
  • Oracle中如何转义单引号? [复制]

    这个问题在这里已经有答案了 我有一列包含某些存储为文本字符串的表达式 其中包括单个引号 例如 错过的交易 包括引号 发生这种情况时如何使用 where 子句 select from table where reason missed tra
  • Oracle - 仅当不存在时才创建索引

    有没有什么方法可以在oracle中创建索引 只有当它们不存在时 就像是 CREATE INDEX IF NOT EXISTS ord customer ix ON orders customer id 仅当索引不存在时添加索引 declar
  • SQL:两个没有完整列匹配的表的并集

    我有一个table A其中有一组列A1 A2和一个具有一组列的 table bB1 B2 碰巧的是A2 B1但其余列不匹配 也不应该匹配 我想附加表格 所以我使用UNION ALL 对于不匹配的列 我使用null as COLUMN NAM
  • 在 C# 中多次使用单个参数的更好方法

    我刚开始使用准备好的语句从数据库查询数据 并且在实现 C 参数 特别是 OracleParameters 时遇到问题 假设我有以下 SQL string sql select from table1 t1 table2 t2 where t
  • 从Oracle表中删除重复行

    我正在 Oracle 中测试某些内容并使用一些示例数据填充表 但在此过程中我不小心加载了重复记录 因此现在我无法使用某些列创建主键 如何删除所有重复行并只保留其中一行 Use the rowid伪列 DELETE FROM your tab
  • 如何使用 Java 创建多个模式连接?

    我必须使用两个数据库 DB2 Oracle 我在 DB2 数据库中有一个名为NAVID 我想使用 Java 为 Oracle 中的所有表创建相同的架构 public class automateExport static String va
  • 如何在可能为空值的字段上创建唯一索引(Oracle 11g)?

    这是包含 3 列的示例表 ID UNIQUE VALUE UNIQUE GROUP ID 我希望可以允许以下记录 1 NULL NULL 2 NULL NULL or 3 NULL 7 4 123 7 or 注意 此条件不允许unique
  • mmap() 和锁定文件

    考虑以下代码片段 故意缺少错误处理 void foo const char path off t size int fd void ret fd open path O RDWR lockf fd F LOCK 0 ret mmap NUL
  • 使用 SYS_CONNECT_BY_PATH 的 Oracle 累积计数

    当我尝试对实际数据执行以下查询时 它返回了更多记录数 请帮助解决这个问题 下面是表 DM TEMP SUMMING DVC BY FW 中的实际数据 device count dmc id firmware version cg id im
  • 如何使用低权限的 PL-SQL 获取 Oracle 中的列数据类型?

    我对 Oracle 数据库中的一些表具有 只读 访问权限 我需要获取某些列的架构信息 我想使用类似于 MS SQL 的东西sp help 我看到此查询中列出了我感兴趣的表 SELECT FROM ALL TABLES 当我运行这个查询时 O
  • Oracle内置函数元数据

    有没有办法获取 Oracle 内置聚合和其他功能的元数据 例如AVG STDDEV SQRT ETC 我需要知道对象 id 和参数元 In the SYS ALL OBJECTS查看我找不到任何有用的东西 我也尝试过搜索SYS ALL AR
  • 如何在Oracle中从表中选择列,*?

    我正在创建很多脚本 有时为了检查表是否根据我的需要进行更新 我会即时编写几个 SELECT 语句 在 SQL SERVER 中你可以这样写 SELECT Column1 FROM MY TABLE 出于可见性原因 这很有用 但是这似乎在 O
  • 自动提取数据 - Oracle SQL Developer

    我通过 SQL Developer 连接到 Oracle 数据库 我想编写一个返回每月数据集的查询 然后将该数据提取到分隔文本文件中 我知道如何做到这一点就好了 我想知道是否有一种方法可以编写一个脚本来运行查询并在一年内逐月提取数据 这样我
  • Oracle:动态设置表中所有 NOT NULL 列以允许 NULL

    我有一个包含 75 多个列的表 几乎所有列都有 NOT NULL 约束 如果执行巨大的更改表修改语句 其中的每一列 我会收到一条错误消息 内容大致为 您不能将此字段设置为 NULL 因为它已经是 NULL 我必须对几个表执行此操作 因此更希
  • Oracle即时客户端和Oracle客户端之间的区别

    Oracle即时客户端和Oracle客户端有什么区别 你能给我解释一下吗 谢谢 Oracle 客户端附带一个安装程序和许多可执行文件 例如 sqlplus tnsping 很完整而且很大 Oracle Instant 客户端是一个基本的轻量
  • SQL 错误:ORA-14006:无效的分区名称

    我正在尝试使用以下 SQL 语句对 Oracle 12C R1 中的现有表进行分区 ALTER TABLE TABLE NAME MODIFY PARTITION BY RANGE DATE COLUMN NAME INTERVAL NUM
  • 以编程方式插入行(父行和子行)

    我正在使用 Spring 和 JDBCTemplate 该场景是 CUSTOMER 表和 ORDERS 表的父子关系 我想做一个插入 例如 1 个客户和 5 个订单 但我不确定如何以编程方式在 CUSTOMER 表中插入一行 如何获取 Or
  • Oracle SQL 函数中可以有 commit 语句吗

    在 SQL 函数中使用 COMMIT 语句是否可能 有意义 从技术上来说 答案是肯定的 你can请执行下列操作 create or replace function committest return number as begin upd

随机推荐

  • web端引入高德地图

    1 安装 amap amap jsapi loader 依赖 高德地图加载器 npm i amap amap jsapi loader S 2 在对应的文件引入依赖或者全局引入 注意 由于高德api文档提示 您在2021年12月02日申请以
  • centos7设置账号密码复杂度、密码有效期、账号锁定、会话超时等策略

    目录 一 设置密码复杂度 二 设置密码有效期 三 设置登陆会话超时 四 设置登陆失败锁定 一 设置密码复杂度 CentOS7 RHEL7 开始使用pam pwquality模块进行密码复杂度策略的控制管理 pam pwquality替换了原
  • html制作动态八卦图源码

    动态八卦图 自动旋转的八卦图 一个html文件就行 如下动态图所示 taijitu html div div
  • 看甲骨文如何在云端一路高歌猛进!

    甲骨文喜欢并购这事儿不假 但更根植于创新 过去的十几年中 甲骨文始终坚持将完整并颇具创新性的云服务提供给用户 所谓完整 也就是需要覆盖端到端的全流程 提及创新 如今的大环境下怎能不将区块链 IoT 甚至是机器学习统统收入囊中 一起植入软件
  • 《大白AI周报》精华内容整理汇总

    在人工智能学习中 大家或多或少都会关注一些公众号 但随着每天信息量的暴增 碎片化的内容让大家应接不暇 如何挖掘有价值的内容 如何快速查阅自己需要的内容 是一个头疼的问题 因此大白每周都会将人工智能领域 几十个公众号每周发布的精华内容汇总起来
  • 带你认识 MySQL 之 MySQL 体系结构

    序 最近一直在忙项目 各种加班加点 项目上线 渐渐的没有了学习的时间 这不 刚这几天才能抽出点时间 忙里偷闲 正在看一本数据库的书籍 相信很多小伙伴们也都看过 MySQL 技术内幕 InnoDB 存储引擎 这本书很详细的讲述了 MySQL
  • 水墨Shader解析

    Chinese Ink wash Painting II Shader 简介 本文尝试对Chinese Ink wash Painting II 来源 https www shadertoy com view DdSyDW 的代码部分进行解
  • 转载:数字图像去噪典型算法及matlab实现 (http://gaochaojs.blog.51cto.com/812546/243961)

    版权声明 原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http gaochaojs blog 51cto com 812546 243961 数字图像去噪典型算法及matlab实现
  • Python爬虫(一):编写简单爬虫之新手入门

    最近学习了一下python的基础知识 大家一般对 爬虫 这个词 一听就比较熟悉 都知道是爬一些网站上的数据 然后做一些操作整理 得到人们想要的数据 但是怎么写一个爬虫程序代码呢 相信很多人是不会的 今天写一个针对新手入门想要学习爬虫的文章
  • Docker的inspect命令查看容器详细信息

    很久之前建的一个容器 今天发现找不到端口信息了 这都是小问题 执行docker inspect命令可以查看容器的详细信息 推荐 不用进入容器内部 命令格式为 docker inspect 想要查看信息的容器id或者容器名字 运行这个命令会返
  • 帮我写一个单连杆柔性机械臂的综述

    答 单连杆柔性机械臂是一种机械臂 它由多个连接器和柔性活动元件组成 它的主要优势在于其轻量级 可编程和低成本 具有良好的机械性能和可扩展性 它可用于模拟复杂的机械任务 例如机器人末端夹持和机械夹具控制 它可以实现高精度和高灵活性的操作 从而
  • buuctf [强网杯 2019]随便注 1

    buuctf web 强网杯 2019 随便注 1 刷题个人日记 小白一个 写给自己看 打开后是这样 从题目和内容来看就是一道sql注入题 输入 1 or 1 1 这个 用来注释掉后面的sql语句 显示所有数据 这个数据有什么用我也不知道
  • 解决:ERROR: Could not build wheels for horovod, which is required to install pyproject.toml-based

    解决 ERROR Could not build wheels for horovod which is required to install pyproject toml based projects 安装horovod的时候报错 由于
  • GetLastError返回值

    GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置 函数并无必要设置上一次错误信息 所以即使一次GetLastError调用返回的是零值 也不能担保函数已成功执行 只有在函数调用
  • KVM内核加载配置及技巧

    KVM 配置及技巧 加载KVM模块 1 检查加载状态 lsmod grep kvm若什么也没显示 说明还未加载 2 显示有哪些可加载模块 find lib modules name kvm 显示如下 lib modules 2 6 32 2
  • 宝塔面板linux在终端使用命令开启服务保持服务不关闭

    我们经常在宝塔面板终端开启服务 比如socket等服务时 如果关闭面板标签页或者关闭终端 服务也随之关闭了 要保持服务一直运行 就需要把终端进程放在linux后台执行 方法如下 1 先Ctrl z 将命令保持挂载 并且能够继续在终端输入其他
  • C语言经典100例题(42)--学习使用auto定义变量的用法

    目录 题目 问题分析 代码 运行结果 题目 学习使用auto定义变量的用法 问题分析 auto存储类型只对属于块的变量有效 auto变量具有自动存储期限 块作用域 并且无连接 auto存储类型几乎从来不用明确地指明 因为对于在块内部声明的变
  • 关于排水管道沉积模拟建模的想法

    首先管道沉积是一个较为复杂的过程 对其分析主要考虑了无机盐所造成的影响 在立项书中 已经给出了各种元素的占比 据此可推理出对沉积起着主导作用的化学反应 在排水管中原本的污水 所以考虑的重点方向就是在特定温度 特定流速下 无机盐的沉积量随时间
  • Shell脚本中字符串截取功能

    在Shell脚本编写中 有几个地方都是要用到字符串截取的功能 那将这块的内容进行下记录 1 字符串变量的截取操作 对字符串变量的截取操作一般都是通过 操作符 的方式进行 1 从指定位置index截取固定长度 格式 string start
  • Oracle中的锁

    Oracle数据库支持多个用户同时与数据库进行交互 每个用户都可以同时运行自己的事务 从而也需要对并发访问进行控制 Oracle也是用 锁 的机制来防止各个事务之间的相互影响 对并发访问进行控制的 保证数据的一致性和完整性 当一个事务或操作