`

Oracle系列之六 锁和闩

阅读更多

一、概述

锁是协调对共享资源访问的一种机制。此处共享资源可能是数据行、表或者别的什么很多人都需要访问的资源。

Oracle数据库实现锁的机制跟别的数据库不同,在Oracle数据库中锁并不算的上是稀缺的资源,当然不合适的持有很多锁一定会降低程序的并发行和扩展性的。

二、锁定问题

考虑下这样一种场景,表T中有一行数据记录了一个人的信息,A和B两个客户端都要去修改,A和B都先获取了这个人的信息,然后A会修改地址,B会修改了证件号码。修改完后A先提交了修改,把用户的信息更新了一遍,提交事务后,B也进行了修改,提交。此时再去查看此人信息,发现A做的修改已经被覆盖,即相当于A没有进行任务操作。

解决问题的办法有两种:悲观锁定乐观锁定

悲观锁定:当一个客户端要修改一条记录的时候, 就把该记录锁定,直到修改完提交了事务,如通过select * from T for update。这种办法当然有很一些问题了,在并发情况下对记录的锁定时间很长,如果是一些比较核心的资源,这种方式会极大降低并发度。在另外一些更新数量的场景下,情况变得更糟糕。

另外,如果是b/s应用模式,这问题就变得复杂了,每次请求一个事务,打开用户信息的时候,事务就已经完了,这种行上的锁也被释放了,等真正更新的时候已经没有了锁。

乐观锁定:我们在修改记录的时候,不像悲观锁定一样,一开始便锁定。而是在开始的时候记录一个关键的信息,等 真正要修改时候根据这个信息来判断我们在开始决定修改的时候到更新时候为止,有没有被别人更新过,如果更新过了,那么我们就提示修改失败,需要重新来修改。此处的关键信息可以是版本列,如时间戳;也可以是校验和,如该行一些关键字段或者所有字段值的hash/md5值,也可以作为一个虚拟列‘存放’hash/md5值。

但是另外考虑一种情况,在修改包含大量信息的表单的时候,用户辛辛苦苦录了半个小时的单据,在提交的时候说表单已经被修改了,你猜猜那会是什么样的情形?所以作为对悲观锁的一种扩展,我们可以在应用层级实现一种锁定,应用层负责添加、释放锁,并负责客户端处理异常终止、会话超时等情形下锁的释放,同时提供应用级锁定的管理功能,可以管理员手动释放锁。

三、锁

1)、DML锁

顾名思义就是执行dml语句时候加的锁,如update、delete、select、insert等。怎么分成tm和tx锁的?在oracle数据库中select语句是从来不加锁的,对于一个大表,你在一个会话中查询还没有完成的时候,可以在另外一个会话中把表给drop掉,第一个会话中的查询会一直进行到查完所有数据。

  a、TX锁

事务锁,属于行级锁,如果当前没有事务,则第一条修改表数据的sql语句将隐式的开启一个新事务,容易update、 delete、 insert语句,同时该事务会持有一个tx锁,这些语句修改的数据也将指向这把tx锁。如果已经有了事务,则直接指向已有的tx锁。

分别用sys和scott连接数据库,然后用sys查看scott持有的锁:

SQL> select sess.username,sess.sid,lck.type,lck.lmode 
	from v$session sess 
	left join v$lock lck on lck.sid = sess.sid 
where sess.username = upper('scott');

USERNAME          SID TYPE      LMODE
--------------------- ---------- ---- ----------
SCOTT                 132 AE            4

然后用scott更新emp的一条记录后再查询锁的信息:

 

SQL> select sess.username,sess.sid,lck.type,lck.lmode
  2     from v$session sess
  3     left join v$lock lck on lck.sid = sess.sid
  4  where sess.username = upper('scott');

USERNAME                    SID TYPE      LMODE
---------------------------- ---------- ---- ----------
SCOTT                          132 AE            4
SCOTT                          132 TM            3
SCOTT                          132 TX            6
   此处多出了一把TX锁。如果继续用scott更新别的表,如dept表,会看到tm锁增加了一把,但是tx锁仍然仍然是一把。

  b、TM锁

表级锁,Enqueue锁,保护表结构不被别的会话修改。当对表数据进行增删改的时候,就会给表加一个TM锁。上边代码中看到,在修改表数据的时候会给表加一把tm锁。

如果一个表加了tm锁,则不能再加ddl排他锁和ddl共享锁了。

如果向表中插入数据后,事务尚未提交,在新会话中再创建索引则会失败,提示(什么锁跟什么锁的问题?):

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

但是如果在在运行创建索引语句但是并未创建完成的时候,另外一个会话中插入数据,会出现数据插入,索引创建会话等待插入数据会话提交事务的现象,为何?

2)、DDL锁

顾名思义是执行ddl语句时候加的锁,如create table、alter table、drop table、truncate table、create index、create view等。

  a、DDL互斥锁(DDL exclusive lock)

表级锁,当对一个表加了ddl互斥锁的时候,别的会话就不能再加ddl锁和dml锁了,修改表结构会被阻塞,查表中的数据也会被阻塞。如alter table,create table,drop table,truncate table等。

  b、DDl共享锁(DDL share lock)

表级锁,当一个表加了ddl共享锁的时候,别的会话只能获得ddl共享锁,不能加dml锁,不能修改表结构,但是可以查询修改表中的数据。如create view,create index等。

  c、可中断解析所(breakable parse lock)

共享池(只有共享池中么?)中一些对象,如执行计划,游标,统计信息等,会对依赖的一些对象,如表,索引等加可中断解析锁。如果被依赖对象发生了变化,如执行了ddl,oracle会查看已经对该对象注册了依赖性的对象列表,使其失效。

ddl锁可以通过dba_ddl_locks视图获取,这是一个建立在x$表上的视图。

一个会话中执行如下sql但并未执行完时:

create index idx_dpt_bk_deptno on scott.dept_bak(deptno);
  另外一会话中执行查询,最后一行就是创建索引的ddl锁。
SQL> select * from dba_ddl_locks;

SESSION_ID OWNER    NAME            TYPE          MODE_HELD    MODE_REQUESTED
---------- ----- ------------------ ------------ ------------- -------------
    190 SYS       "SYS"."ALERT_QUE":"HAE_SUB"    28         Null      None
    190 SYS       "SYS"."ALERT_QUE":"HAE_SUB"    28         Null      None
    190 SYS       STANDARD           Table/Procedure/Type      Null      None
    190 SYS       DBMS_PRVT_TRACE          Table/Procedure/Type      Null      None
    191 SYS       IS_VPD_ENABLED        Table/Procedure/Type      Null      None
    190 SYS       "SYS"."ALERT_QUE":"YYMT_1830_O    28         Null      None
    190 SYS       AQ$_ALERT_QT_E        10         Null      None
    191 SYS       DBMS_APPLICATION_INFO       Body          Null      None
    190 SYS       DBMS_HA_ALERTS_PRVT         Table/Procedure/Type      Null      None
    191 SYS       SQL_TXT            Table/Procedure/Type      Null      None
    191 SCOTT     IDX_DPT_BK_DEPTNO        Index         Exclusive    None

四、闩

闩是一种低级串行化设备,用来协调对内存结构如数据库块缓冲区缓存和共享池中的库缓存、对象、文件等资源的并发访问。

闩设计为只持有很短的一小段时间,获取闩的时候,如果获取不到则休眠一小段时间后继续获取,不会排队等待。而enqueue锁是队列锁,如果获取队列锁获取不到则会排队。

在获取不到闩的时候,就会出现“自旋”,即在循环中不断重复的去获取闩。因为进程上下文切换的的代价很高,而闩本身被设计为持有很小一段时间的设备,所以进程在被踢出cpu之前会不断重复的试图获取栓,如果循环了一定次数后仍然获取不到,就会被踢出cpu。这个循环的次数可以通过参数设置,默认为2000.可以通过statspack或v$latch视图来查看视图获取栓的信息。

可以通过硬解析和软解析的例子来进一步了解一些闩的细节

五、手动锁定和用户定义锁

1)手动锁定:通过select ···· for update 或lock table手工锁定

2)用户自定义锁:通过dbms_lock包可以创建用户过户自定义锁。


分享到:
评论

相关推荐

    知攻善防-应急响应靶机-web2.z18

    知攻善防-应急响应靶机-web2.z18

    知攻善防-应急响应靶机-web2.z09

    知攻善防-应急响应靶机-web2.z09

    白色简洁风格的影视众筹平台整站网站源码下载.zip

    白色简洁风格的影视众筹平台整站网站源码下载.zip

    HTTP请求流程深入解析与性能优化技术指南

    内容概要:本文详细解析了HTTP请求的整个流程,包括用户请求发起、请求报文构建、服务器处理请求、响应报文生成、网络传输响应和浏览器接收响应六个阶段。每个阶段的内容均涵盖了关键步骤和技术细节,如DNS解析、TCP连接、缓存策略、HTTP/2性能提升、HTTPS加密等。通过这些内容,读者可以全面理解HTTP请求的完整流程。 适合人群:具备一定网络基础知识的前端、后端开发人员及IT运维人员。 使用场景及目标:适用于希望深入了解HTTP协议及其优化技术的技术人员,有助于提升系统的性能和安全性,优化用户体验。 阅读建议:本文内容详尽且涉及多个关键技术点,建议读者结合实际案例进行学习,逐步理解和掌握各个阶段的技术细节和优化方法。

    白色简洁风格的电话通讯公司模板下载.zip

    白色简洁风格的电话通讯公司模板下载.zip

    白色简洁风格的日历当日事件提醒整站网站源码下载.zip

    白色简洁风格的日历当日事件提醒整站网站源码下载.zip

    RX8 专业消人声 乐器 软件

    一键制作 歌曲伴奏! 可以消人声 吉他 鼓 等 多轨道声音。相当好用。

    知攻善防-应急响应靶机-web2.z04

    知攻善防-应急响应靶机-web2.z04

    NSDocumentError如何解决.md

    NSDocumentError如何解决.md

    白色宽屏风格的大气冲浪运动整站网站模板.rar

    白色宽屏风格的大气冲浪运动整站网站模板.rar

    白色简洁风格的婴儿用品商城网站模板.zip

    白色简洁风格的婴儿用品商城网站模板.zip

    罗兰贝格2023未来营养趋势报告21页

    罗兰贝格2023未来营养趋势报告21页

    html+css 圣诞树代码html

    预览地址:https://blog.csdn.net/qq_42431718/article/details/144749829 html+css 圣诞树代码html

    小学生出题软件v6.3.3.zip

    1-100加减乘除出题生成器

    白色简洁风格的网络实验室CSS模板.zip

    白色简洁风格的网络实验室CSS模板.zip

    白色简洁风格的企业产品展示整站网站源码下载.zip

    白色简洁风格的企业产品展示整站网站源码下载.zip

    etcd服务器性能指标与状态监控数据

    内容概要:《etcd-metrics-latest.txt》文档记录了 etcd(一个分布式键值存储系统)的多个指标数据,包括但不限于集群版本、认证修订版、后端磁盘操作延时分布、租赁管理、键值操作统计、快照保存、网络通信、Go 运行时指标、gRPC 请求处理、操作系统资源使用以及进程资源使用等。这些指标提供了详细的性能监测数据,帮助运维人员和开发人员理解和优化 etcd 集群的运行状态。 适合人群:具有基础计算机科学知识的运维人员或开发人员,尤其是负责维护或开发基于 etcd 技术系统的专业人员。 使用场景及目标:主要用于监控 etcd 集群的健康状况,评估性能瓶颈,辅助故障排查,支持集群的持续优化和技术决策。 其他说明:文档中大量使用了指标和术语,建议读者对 etcd、Go 语言、gRPC 和操作系统基础知识有一定的了解,以便更好地解读文档中的数据。对于不熟悉这些技术的读者来说,可能需要额外查阅相关资料来辅助理解。

    (1866400)java编的计算器程序

    Java编写的计算器程序是一种基于Java编程语言实现的计算工具,常用于教学或个人项目中,以帮助用户执行基本的数学运算。在这个简单的计算器程序中,我们可能会遇到以下几个关键的Java知识点: 1. **基础语法与控制结构**:Java的基础语法包括变量声明、数据类型(如int、double等)、条件语句(if-else)和循环语句(for, while)。在计算器程序中,这些元素用于读取用户输入、判断操作类型以及重复执行某些计算过程。 2. **面向对象编程**:Java是一种面向对象的语言,因此计算器程序可能包含多个类,如Calculator类、Button类(模拟图形界面的按钮)和Display类(显示计算结果)。类之间可能存在继承关系,例如Button类可能继承自一个抽象的UIComponent类。 3. **输入/输出处理**:在命令行计算器中,Java的Scanner类用于获取用户输入,如数字和运算符。在图形用户界面(GUI)计算器中,可能使用事件监听器处理用户的点击事件,获取按钮上的文字信息。 4. **异常处理**:为了确保程序的健壮性,计算器可能包含异常处理代码,比如当

    SystemExit.md

    SystemExit.md

    NavigationGuardError解决办法.md

    NavigationGuardError解决办法.md

Global site tag (gtag.js) - Google Analytics