锁是并发访问的时候用于保护不共享资源不被同时并发修改的机制。
oracle锁分为DML锁,DDL锁,内部锁和latch
DML锁确保一次只能只有一个人修改某一行(TX锁),而且正在处理一个表时别人不能删除(TM锁)。
DDL锁,在DDL操作是系统会自动为对象加上DDL锁,保护这些对象不被其他会话锁修改。
latch是轻量级的串行化设备,用于协调对共享数据结构、对象、文件的多用户访问,一般都是保护共享内存结构使用的锁,在此不做讨论。
一般的锁管理器工作过程:
1.找到想要锁定的那一行地址
2.在锁管理器排队
3.锁定列表
4.搜索列表,查看别人是否锁定这一行
5.在列表中创建一个新的条目,表明已经锁定这一行
6.对列表解锁
接下里修改,之后提交修改后,继续过程:
7.再次排队
8.锁住锁的列表
9.在这个列表中锁定,并释放所有的锁
10.对列表解锁

oracle锁管理方式:
找到需要锁定的那行地址
到达那一行
锁定这一行

通常lock有三个组件:Resource Structure(资源)、Lock Structure(锁)和Enqueue(排队机制)
Resource和lock是数据结构,而Enqueue是算法。
Resource Structure每一个需要并发控制的资源都有用这个数据结构来描述,先关的成员为:owner、waiter和converter,这是三个指针,分别指向3个由Lock Structure组成的链表。
Lock Structure
每当进程需要访问共享资源时,必须先“锁定”该资源,这个动作实际上是从内存中申请一个Lock Structure,
,在其中记录“锁模式、进程ID”等重要信息。然后看是否立即能够获得资源的访问权,如果不能的话将这个Lock structure挂到Resource Structure的Waiter链表中,如果能够获得,则把Lock Structure的owner链表中。

最常用的锁模式
Share 拥有这对资源进行只读访问,允许其他用户并发只读访问
Exclusive 拥有者对资源进行修改访问,不允许其他用户并发访问

Enqueue 算法
Lock使用的是Enqueue算法,可以理解为“先入先出队列”,如果进程的锁定请求不能满足,该进程的Lock Structure就被加到Waiter链表的末端。当占用进程释放锁时,会检查Waiter和Converter队列,把锁分配给先入对的请求者。converter和waiter两个等待队列,算法的有些区别:如果某个操作先后需要2中不同模式的锁,比如先是share mode然后是exclusive mode,则进程会先请求share mode 后获得lock structure会挂在owner队列上,当需要exclusive mode锁时,进程先释放share mode的锁,然后再次申请exclusive mode的锁,但是可能无法立即获得,这时请求会挂在converter队列下,converter队列会被优先于waiter队列处理。

oracle行级锁机制
首先明白三个概念:
ITL:每个数据块的头部有一个叫做ITL的数据结构,用于记录那些事务修改了这个数据块的内容。
记录头ITL索引:每条记录的记录头部有一个字段,用于记录ITL表项号,可以看做指向ITL表的指针
TX锁,事务锁
TM锁:保护表或视图定义不被修改的锁

当一个事务开始时,必须申请一个TX锁,这种锁保护资源是回滚段、回滚段数据块,因此这个这个申请意味着:用户进程必须先申请到回滚段资源后才能开始一个事务,才能执行DML语句修改数据。
申请到回滚段资源后,用户事务就可以开始修改数据了,事务信息可在v$transaction中查到,在修改数据表的记录时,需要遵守如下操作顺序:
首先获得这个表的TM锁,这个锁用于保护事务执行过程中其他用户不能修改表结构;
事务修改某个数据块记录时,首先需要在改数据块块头的ITL表中申请一个空闲表项,并在其中记录事务号,实际就是在记录这个事物要使用的回滚段地址;
事务修改该数据块的某条记录时,会设置该记录头部的ITL索引指向上一步申请到的表项,然后再修改记录内容,修改前先在回滚段对记录修改前的状态做一个拷贝,然后才能修改数据记录,这个拷贝用于以后的回滚、恢复和一致性读。当其他用户并发修改这条记录时,会根据记录头的ITL索引读取ITL表项内容,查看这个事务是否已经提交,如果没有提交,则这个用户的TX锁会等待前一个用户的TX锁的释放。
例如如下式转储的一个数据块的ITL信息:
Block header dump:  0×00411819
Object id on Block? Y
seg/obj: 0x10396  csc: 0×00.d62e7  itc: 2  flg: O  typ: 1 – DATA
fsl: 0  fnx: 0×0 ver: 0×01

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0×0008.00b.0000029b  0x00c05271.006a.3c  —-    3  fsc 0×0000.00000000
0x02   0×0000.000.00000000  0×00000000.0000.00  —-    0  fsc 0×0000.00000000
seg/obj:seg/obj id
csc:clean scn
itc:itl slots的个数,此时多少个事务在对本data block进行操作
flg: 0=on the freelist
typ:数据块类型
fsl: itl tx freelist slot
fnx: dba of next block on freelist
Itl:interested transaction list index
Xid:transaction id
Uba:undo address
Flag:事务状态标志
Lck:事物所影响行的数量

oracle 在对数据行锁定时,行指向事务ID的一个副本,事务ID存储在包含数据的块中,释放锁时,事务ID会保存下来,这个事务ID时事务特有的,表示了回滚段号、槽和序列号,事务ID留在包含数据行的块中,可以告诉其他会话:一个会话拥有这个数据行。另一个会话会看到锁ID,由于锁ID表示一个事务,所以可以很快的查看持有这个锁的事务是否活动的。如果锁不活动的,则允许会话访问这个数据,如果锁还是活动的,会话会要求一旦释放锁就得到通知。所以这需要一个排队机制:请求锁的会话会排队,等待目前拥有这个锁的事务执行,然后的到这个数据。可以根据v$lock视图的lmode和request mode判断谁是owner、waiter和converter
owner:lomode>0,request=0
waiter:lmode=0,request>0
converter:lmode>0,request>0

例如下试验可以清楚看到这些信息:
系统已更改。
SQL> create table t1 ( x int );
表已创建。
SQL> create table t2 ( x int );
表已创建。
SQL> insert into t1 values ( 1 );
已创建 1 行。
SQL> insert into t2 values ( 1 );
已创建 1 行。
SQL> select (select username
2                 from v$session
3                 where sid = v$lock.sid) username,
4         sid,
5         id1,
6         id2,
7         lmode,
8         request, block, v$lock.type
9    from v$lock
10   where sid = (select sid
11                  from v$mystat
12                 where rownum=1)
13  /

USERNAME  SID   ID1   ID2   LMODE  REQUEST    BLOCK    TYPE
——– —–  —-   —-  —–   ——-   —–    —-

SYS       13    66455   0     3        0         0      TM

SYS       13    66456   0     3        0         0      TM

SYS       13    589840  662   6        0         0      TX

SQL> select object_name, object_id
2    from user_objects
3   where object_name in (‘T1′,’T2′)
4  /

OBJECT_NAME    OBJECT_ID
————  ———
T1            66455
T2            66456
每个事务只能有一个TX锁,但是TM锁依照修改的对象个数而定,TM对应的ID1列就是DML锁定对象ID.
SQL> select username,
2         v$lock.sid,
3         trunc(id1/power(2,16)) rbs,
4         bitand(id1,to_number(‘ffff’,'xxxx’))+0 slot,
5         id2 seq,
6         lmode,
7         request
8  from v$lock, v$session
9  where v$lock.type = ‘TX’
10    and v$lock.sid = v$session.sid
11    and v$session.username = USER;

USERNAME  SID    RBS    SLOT   SEQ   LMODE  REQUEST
——– —– ——  —–  —— —— ———
SYS       13     9      16      662       6     0

SQL> select XIDUSN, XIDSLOT, XIDSQN  from v$transaction;

XIDUSN    XIDSLOT     XIDSQN
—— ———- ———-
9         16        662

oracle事务不同于其他数据库之处,不需要专门语句显示开始事务,事务会在修改数据的第一条语句处开始,但是一定要用commit或rollback事务。
oracle的commit做了如下操作:
为事务生成一个SCN
LGWR将所有余下的缓存重做日志条目写至磁盘,并把SCN记录到在线重做日志文件中
v$lock中记录着会话持有的锁,这些锁将被释放,而排队等待这些锁的每一个队列都会被唤醒
如果事务处理的某些块还在缓存中,则会快速的模式访问并清除
Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0×0008.00b.0000029b  0x00c05271.006a.3c  C—    0  scn 0×0000.000d6470
0x02   0×0005.007.00000372  0x00c0dbca.006e.2f  –U-    1  fsc 0×0000.000d6584
如上的flag列,第一条ITL信息显示数据块当前事务信息已经被清除,第二个还未清除事务ITL信息标志为U;
oracle并发支持,实现了一种多版本体系,能够同时物化多个版本的数据,能够提供读一致性机制,数据读取器绝不会被写入器所阻塞,也就是写不会阻塞读。一种情况例外,那就是在分布式事务处理(2PC)期间。
另外,记住大多数DDL都带排它锁,有些DDL没有DDL锁,如create index idx on t(x) online;online关键字会改变建立索引的方法。oracle只会得到表上的TM锁,防止其他DDL发生,但是运行DML运行。oracle发生死锁的原因外键未加索引、位图索引发生更新,外键未加索引更新或删除父表都会对整个子表加锁
会话1:
create table p ( x int primary key );
create table c ( x references p );
insert into p values ( 1 );
insert into p values ( 2 );
commit;
insert into c values ( 2 );
会话2:
delete from p where x = 1;;
这个时候机会发生阻塞:
SQL> select
2        (select username from v$session where sid=a.sid) blocker,
3         a.sid,
4        ‘ is blocking ‘,
5         (select username from v$session where sid=b.sid) blockee,
6             b.sid
7    from v$lock a, v$lock b
8   where a.block = 1
9     and b.request > 0
10     and a.id1 = b.id1
11     and a.id2 = b.id2;

BLOCKER    SID ‘ISBLOCKING’  BLOCKEE     SID
——-  —–  ———   ——— ——-
SYS       142  is blocking  SYS          13
不需要对外键加索引的情况:
1、没有从父表删除行
2、没有更新父表的唯一键/主键值
3、没有从父表联结子表
参考:
TOM oracle 9i&10g编程艺术

oracle的锁与并发机制的更多相关文章

  1. ORACLE的锁机制

    数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性. 加锁是实现数据 ...

  2. 第二十节: 深入理解并发机制以及解决方案(锁机制、EF自有机制、队列模式等)

    一. 理解并发机制 1. 什么是并发,并发与多线程有什么关系? ①. 先从广义上来说,或者从实际场景上来说. 高并发通常是海量用户同时访问(比如:12306买票.淘宝的双十一抢购),如果把一个用户看做 ...

  3. oracle 事务 锁机制

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

  4. Java 并发机制底层实现 —— volatile 原理、synchronize 锁优化机制

    本书部分摘自<Java 并发编程的艺术> 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JV ...

  5. 从浅到深掌握Oracle的锁

      1.分别模拟insert,update和delete造成阻塞的示例,并对v$lock中的相应的信息进行说明,给 出SQL演示. Insert示例 会话:SQL> select * from ...

  6. [数据库锁机制] 深入理解乐观锁、悲观锁以及CAS乐观锁的实现机制原理分析

    前言: 在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念.数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务 ...

  7. sqlserver 并发机制

    一.事务四大属性 分别是原子性.一致性.隔离性.持久性. 1.原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库, ...

  8. Oracle关于锁的几种类型和参数

    设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据的一致性和准确性.Oracle数据库封锁方式有三种:共享封锁,独占封锁,共享更新封锁 封锁类型 Oracle RDBMS的封锁类型可分 ...

  9. Oracle的锁

    Oracle数据库中的锁机制 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数 ...

随机推荐

  1. Apache的安装与下载

    PHP的运行必然少不了服务器的支持,何为服务器?通俗讲就是在一台计算机上,安装个服务器软件,这台计算机便可以称之为服务器,服务器软件和计算机本身的操作系统是两码事,计算机自身的操作系统可以为linux ...

  2. 使用shell脚本生成数据库markdown文档

    学习shell脚本编程的一次实践,通过shell脚本生成数据库的markdown文档,代码如下: HOST=xxxxxx PORT=xxxx USER="xxxxx" PASSWO ...

  3. Leetcode 567.字符串的排列

    字符串的排列 给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列. 换句话说,第一个字符串的排列之一是第二个字符串的子串. 示例1: 输入: s1 = "ab&q ...

  4. STL之string使用简介

    声明一个C++字符串 string类的构造函数和析构函数如下: string s; //生成一个空字符串s string s(str) //拷贝构造函数 生成str的复制品 string s(str, ...

  5. getRequestURI,getRequestURL的区别,获取各种路径的方法

    getRequestURI,getRequestURL的区别 test1.jsp======================= <a href ="test.jsp?p=fuck&qu ...

  6. java的ArrayList使用方法详解

    ArrayList是Java的链表类,在项目开发中十分常见,那么怎样对ArrayList进行添加.删除.修改.查询.遍历呢?本文将进行详细阐述. 工具/原料   java 一.ArrayList的添加 ...

  7. ftp下出现“当前的安全设置不允许从该位置下载文件”提示

    在资源管理器中使用ftp协议下载文件时,提示“当前的安全设置不允许从该位置下载文件”,下载失败. 解决方法: 1.在自己的电脑上打开Internet选项

  8. GDOI2018 爆零记,Challenge Impossibility

    蒟蒻的GDOI又双叒叕考挂啦...... Day 0 && Day -1 学校月考,貌似考的还不错? 然而考完试再坐船去中山实在是慢啊......晚上10点才到酒店 wifi差评... ...

  9. 阿里系产品Xposed Hook检测机制原理分析

    阿里系产品Xposed Hook检测机制原理分析 导语: 在逆向分析android App过程中,我们时常用的用的Java层hook框架就是Xposed Hook框架了.一些应用程序厂商为了保护自家a ...

  10. bzoj4292 PA2015 Równanie 枚举

    貌似应该是找出n后,带回去看看是不是对的. #include<cstdio> #include<cstring> #include<algorithm> #incl ...