ORACLE的锁机制

时间:2022-10-28 16:34:06

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。 
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

Oracle数据库的锁类型 
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护 数据库的内部结构。 
DML锁的目的在于保证并发情况下的数据完整性,。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X 等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

在数据行上只有X锁(排他锁)。在Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行 DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

悲观*和乐观* 
一、悲观* 
锁在用户修改之前就发挥作用: 
Select ..for update(nowait) 
Select * from tab1 for update 
用户发出这条命令之后,oracle将会对返回集中的数据建立行级*,以防止其他用户的修改。 
如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。 
1:对返回结果集进行update或delete操作会发生阻塞。 
2:对该表进行ddl操作将会报:Ora-00054:resource busy and acquire with nowait specified. 
原因分析 
此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback. 
同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.

二、乐观* 
乐观的认为数据在select出来到update进取并提交的这段时间数据不会被更改。这里面有一种潜在的危险就是由于被选出的结果集并没有被锁定,是存在一种可能被其他用户更改的可能。因此Oracle仍然建议是用悲观*,因为这样会更安全。

阻塞 
定义: 
当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。4个常见的dml语句会产生阻塞 
INSERT 
UPDATE 
DELETE 
SELECT…FOR UPDATE

INSERT 
Insert发生阻塞的唯一情况就是用户拥有一个建有主键约束的表。当2个的会话同时试图向表中插入相同的数据时,其中的一个会话将被阻塞,直到另外一个会话提交或会滚。一个会话提交时,另一个会话将收到主键重复的错误。回滚时,被阻塞的会话将继续执行。 
UPDATE 和DELETE当执行Update和delete操作的数据行已经被另外的会话锁定时,将会发生阻塞,直到另一个会话提交或会滚。 
Select …for update 
当一个用户发出select..for update的错作准备对返回的结果集进行修改时,如果结果集已经被另一个会话锁定,就是发生阻塞。需要等另一个会话结束之后才可继续执行。可以通过发出 select… for update nowait的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified. 
死锁-deadlock 
定义:当两个用户希望持有对方的资源时就会发生死锁. 
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚. 
例子: 
1:用户1对A表进行Update,没有提交。 
2:用户2对B表进行Update,没有提交。 
此时双反不存在资源共享的问题。 
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。 
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。 
起因
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。

DML锁分类表 
表1Oracle的TM锁类型 
锁模式 锁描述 解释 SQL操作 
0 none 
1 NULL 空 Select 
2 SS(Row-S) 行级共享锁,其他对象 
只能查询这些数据行 Select for update、Lock for 
update、Lock row share 
3 SX(Row-X) 行级排它锁, 
在提交前不允许做DML操作 Insert、Update、 
Delete、Lock row share 
4 S(Share) 共享锁 Create index、Lock share 
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive 
6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive 
oracle 锁问题的解决

可以用Spotlight软件对数据库的运行状态进行监控。 
当出现session锁时,我们要及时进行处理. 
1. 查看哪些session锁: 
SQL语句:select 'alter system kill session '''||sid||','||serial#||''';' from v$session where sid in (select sid from v$lock where block = 1); 
SQL> select 'alter system kill session '''||sid||','||serial#||''';' from v$session where sid in (select sid from v$lock where block = 1); 
'ALTERSYSTEMKILLSESSION'''||SID||','||SERIAL#||''';' 
-------------------------------------------------------------------------------- 
alter system kill session '132,731'; 
alter system kill session '275,15205'; 
alter system kill session '308,206'; 
alter system kill session '407,3510'; 
2. 查看session锁. 
sql语句:select s.sid, q.sql_text from v$sqltext q, v$session s 
where q.address = s.sql_address 
and s.sid = &sid 
order by piece; 
SQL> select s.sid,q.sql_text from v$sqltext q, v$session s where q.address = s.sql_address and s.sid in (select sid from v$lock where block = 1) order by piece; 
SID SQL_TEXT 
---------- ---------------------------------------------------------------- 
77 UPDATE PROFILE_USER SET ID=1,COMPANY_ID=2,CUSTOMER_ID=3,NAMED 
77 _INSURED_ID=4,LOGIN=5,ROLE_ID=6,PASSWORD=7,EMAIL=8,TIME_ZON 
77 E=9 WHERE PROFILE_USER.ID=:34 
3 rows selected.

3. kill锁的进程. 
SQL语句:alter system kill session '77,22198'; 
SQL> alter system kill session '391,48398'; 
System altered. 
4. 查看谁锁了谁。 
select s1.username || [email='@']'@'[/email] || s1.machine 
|| ' ( SID=' || s1.sid || ' ) is blocking ' 
|| s2.username || [email='@']'@'[/email] || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status 
from v$lock l1, v$session s1, v$lock l2, v$session s2 
where s1.sid=l1.sid and s2.sid=l2.sid 
and l1.BLOCK=1 and l2.request > 0 
and l1.id1 = l2.id1 
and l2.id2 = l2.id2 ; 
注: 
> : 重定向输出,将文件的标准输出重新定向输出到文件,或将数据文件作为另一程序的标准输入内容。 
| :UNIX管道:将一文件的输出作为另一文件的输入. 
在执行SQL语句试:alter system kill session '391,48398'(sid为391); 应当注意对于sid在100以下的应当谨慎,可能该进程对应某个application,如对应某个事务,可以kill.

ORACLE的锁机制的更多相关文章

  1. oracle 事务 锁机制

    原文地址:http://www.cnblogs.com/quanweiru/archive/2013/05/24/3097367.html 本课内容属于Oracle高级课程范畴,内容略微偏向理论性,但 ...

  2. oracle锁机制

    1 前言 数据库大并发操作要考虑死锁和锁的性能问题.看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据 库执行请求,T2代表另一个请求,也可以理解为T1为 ...

  3. Oracle 锁机制探究

    以前虽然在网上看到很多关于Oracle锁机制的描述,但总感觉哪里有缺陷不适合自己,因此花了点时间参考官网以及Tom Tyke的<Oracle 9i/10g/11g编程艺术>一书整理了一下O ...

  4. 【转载并整理】ORACLE锁机制

    转载文章:http://blog.csdn.net/liuyiy/article/details/25005393 转载文章:http://www.cnblogs.com/jiyuqi/p/37017 ...

  5. Oracle 锁机制

    本文参考自:ORACLE锁机制 1.oracle是一个多用户使用的共享资源,当多个用户并发的操作同一数据行时,那么在oracle数据库中就会存在多个事务操作统一数据行的操作,如果不对并发操作进行控制, ...

  6. oracle的锁与并发机制

    锁是并发访问的时候用于保护不共享资源不被同时并发修改的机制.oracle锁分为DML锁,DDL锁,内部锁和latch DML锁确保一次只能只有一个人修改某一行(TX锁),而且正在处理一个表时别人不能删 ...

  7. ORACLE【2】:锁机制及解锁

    1. 锁的基本知识 根据要保护的对象不同,oracle的数据锁可以分成以下几类:DML锁,(data locks)数据锁,用于保护数据的完整性:DDL锁(dictionary locks),用于保护数 ...

  8. Hibernate中的锁机制

    锁机制:是数据库为了保证数据的一致性<一个事务的各种操作不相互影响>而使各种共享资源在被并发访问访问变得有序所设计的一种规则,用来保证在当前用户进行操作数据的时候其他的用户不能对同一数据进 ...

  9. MySQL学习笔记十六:锁机制

    1.数据库锁就是为了保证数据库数据的一致性在一个共享资源被并发访问时使得数据访问顺序化的机制.MySQL数据库的锁机制比较独特,支持不同的存储引擎使用不同的锁机制. 2.MySQL使用了三种类型的锁机 ...

随机推荐

  1. KOTLIN开发语言文档(官方文档) -- 入门

    网页链接:https://kotlinlang.org/docs/reference/basic-syntax.html 1.   入门 1.1.  基本语法 1.1.1.   定义包 包说明应该在源 ...

  2. c&num;smtp多线程

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. 调用robustfit函数作稳健回归

    调用robustfit函数作稳健回归 regress函数和regstats函数利用普通最小二乘法估计模型中的参数,参数的估计值受异常值的影响比较大.robustfit函数采用加权最小二乘法估计模型中的 ...

  4. gcc&colon; error trying to exec &&num;39&semi;cc1plus&&num;39&semi;&colon; execvp&colon; no such file or directory

    最近在安装OpenCV cmake的时,出现gcc: error trying to exec 'cc1plus': execvp: no such file or directory的错误. 导致问 ...

  5. Linux进程间通信——使用信号量

    这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...

  6. SICP 解题集 — SICP 解题集

    SICP 解题集 — SICP 解题集 SICP 解题集¶ 这个文档的目标是成为中文化的.完整的<计算机程序的构造和解释>一书的解题集. 这个解题集的特色是: 对于每道习题,除了习题答案之 ...

  7. ECMAScript版本号总结

      最近想要研究下ES6,关于这个标准的发展历史.ES5. ES6.ES2015等等名称的定义都不怎么明确,查了很多资料,去除了程序员不关心的信息,下面是对ECMAScript规范发展历史及名词定义的 ...

  8. Hadoop之RPC简单使用&lpar;远程过程调用协议&rpar;

    一.RPC概述 RPC是指远程过程调用,也就是说两台不同的服务器(不受操作系统限制),一个应用部署在Linux-A上,一个应用部署在Windows-B或Linux-B上,若A想要调用B上的某个方法me ...

  9. Universal-Image-Loader 图片异步加载类库的使用

    这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 可是有的人并不知道如何去使用这库如何进行配置,网上查到的信息对于刚 ...

  10. gitlab使用过程中的需求与解决

    序言 在git使用过程中发现指令实在太多,就算记忆后不长用的话很快也会忘记掉,所以编写本文的初衷是为了记录在使用git指令的过程中所遇到的需求与解决方法,毕竟使用git的需求也就那么一些,范围不大,所 ...