oracle的TM锁、TX锁

一.基本概念

Oracle数据库的锁类型

         oracle官方文档里面关于锁的定义:Locks are mechanisms that prevent destructive interaction between transactions accessing the same resource—either user objects such as tables and rows or system objects not visible to users, such as shared data structures in memory and data dictionary rows.

         这段话的大概意思是说锁的作用用来保护tables、rows、shared data structures in memory and data dictionary rows等在交互访问的时候不会被破坏。

        根据保护的对象不同,Oracle数据库锁可以分为以下几大类:

(1)  DML锁(data locks,数据锁),用于保护数据的完整性;

(2)  DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;

(3)  内部锁和闩(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的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

  

二.常见DML锁分类

DML锁分类表

表1 Oracle的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里锁有以下几种模式:

  0:none
  1:null 空
  2:Row-S 行共享(RS):共享表锁
  3:Row-X 行专用(RX):用于行的修改
  4:Share 共享锁(S):阻止其他DML操作
  5:S/Row-X 共享行专用(SRX):阻止其他事务操作
  6:exclusive 专用(X):独立访问使用
  
    数字越大锁级别越高, 影响的操作越多。

  1级锁有:Select,有时会在v$locked_object出现。
  2级锁有:Select for update,Lock For Update,Lock Row Share
  select for update当对话使用for update子串打开一个光标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其它对象只能查询这些数据行,不能进行update、delete或select for update操作,insert的操作还是可以的

(但是在11g的实验中使用select for update产生的锁确实3级锁)
  3级锁有:Insert, Update, Delete, Lock Row Exclusive
  没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。
  4级锁有:Create Index, Lock Share locked_mode为2,3,4不影响DML(insert,delete,update,select)操作, 但DDL(alter,drop等)操作会提示ora-00054错误。
  ORA-00054: resource busy and acquire with NOWAIT specified
  (ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源)
  5级锁有:Lock Share Row Exclusive
  具体来讲有主外键约束时update / delete ... ; 可能会产生4,5的锁。
  当对父表进行修改时,若子表对应的记录存在,则产生ORA-02292异常;否则只对父表加TX锁和RX锁;
   当对子表进行修改时,则除了对子表加加TX锁和RX锁外;对父表也加了加SS锁,这符合逻辑,因为父表此时必须满足参考完整性;也就是,对父表加SS锁,避免此时对父表进行修改操作。上面锁说的修改,都是对子父表存在参考完整性的字段操作的。
  6级锁有:Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive

三.常见相关锁的视图

1.关于V$lock表和相关视图的说明

 

 Column

Datatype

  Description

  ADDR

RAW(4 | 8)

  Address of lock state object

  KADDR

RAW(4 | 8)

  Address of lock

  SID

NUMBER

  Identifier for session holding or acquiring the lock

  TYPE

VARCHAR2(2)

  Type of user or system lock

  The locks on the user types are obtained by user applications. Any process that is    blocking others is likely to be holding one of these locks. The user type locks are:

  TM - DML enqueue   

  TX - Transaction enqueue

  UL - User supplied

  --我们主要关注TX和TM两种类型的锁

  --UL锁用户自己定义的,一般很少会定义,基本不用关注

  --其它均为系统锁,会很快自动释放,不用关注

  ID1

NUMBER

  Lock identifier #1 (depends on type)

  ID2

NUMBER

  Lock identifier #2 (depends on type)

  ---当lock type 为TM时,id1为DML-locked object的object_id

  ---当lock type 为TX时,id1为usn+slot,而id2为seq。

  --当lock type为其它时,不用关注

  LMODE

NUMBER

  Lock mode in which the session holds the lock:

  0 - none

  1 - null (NULL)

  2 - row-S (SS)

  3 - row-X (SX)

  4 - share (S)

  5 - S/Row-X (SSX)

  6 - exclusive (X)

  --大于0时表示当前会话以某种模式占有该锁,等于0时表示当前会话正在等待该锁资    源,即表示该会话被阻塞。

  --往往在发生TX锁时,伴随着TM锁,比如一个sid=9会话拥有一个TM锁,一般会拥有一个或几个TX锁,但他们的id1和id2是不同的,请注意

 REQUEST

NUMBER

Lock mode in which the process requests the lock:

  0 - none

  1 - null (NULL)

  2 - row-S (SS)

  3 - row-X (SX)

  4 - share (S)

  5 - S/Row-X (SSX)

  6 - exclusive (X)

--大于0时,表示当前会话被阻塞,其它会话占有改锁的模式

CTIME

NUMBER

Time since current mode was granted

BLOCK

NUMBER

The lock is blocking another lock

0, 'Not Blocking',
1, 'Blocking',
2, 'Global',

--该锁是否阻塞了另外一个锁

2.其它相关视图说明

视图名

描述

主要字段说明

v$session

查询会话的信息和锁的信息。

sid,serial#:表示会话信息。

program:表示会话的应用程序信息。

row_wait_obj#:表示等待的对象,和dba_objects中的object_id相对应。

lockwait :该会话等待的锁的地址,与v$lock的kaddr对应.

v$session_wait

查询等待的会话信息。

sid:表示持有锁的会话信息。

Seconds_in_wait:表示等待持续的时间信息

Event:表示会话等待的事件,锁等于enqueue

 

 

 

dba_locks

对v$lock的格式化视图。

Session_id:和v$lock中的Sid对应。

Lock_type:和v$lock中的type对应。

Lock_ID1: 和v$lock中的ID1对应。

Mode_held,mode_requested:和v$lock中

的lmode,request相对应。

v$locked_object

只包含DML的锁信息,包括回滚段和会话信息。

Xidusn,xidslot,xidsqn:表示回滚段信息。和

v$transaction相关联。

Object_id:表示被锁对象标识。

Session_id:表示持有锁的会话信息。

Locked_mode:表示会话等待的锁模式的信

息,和v$lock中的lmode一致。

 

四.常见的SQL查询

1.查询数据库中的锁

select * from v$lock;
select * from v$lock where block=1;

2.查询被锁的对象

select * from v$locked_object;

3.查询阻塞

查被阻塞的会话
select * from v$lock where lmode=0 and type in ('TM','TX');

查阻塞别的会话锁
select * from v$lock where lmode>0 and type in ('TM','TX');

4.查询数据库正在等待锁的进程

select * from v$session where lockwait is not null;

5.查询会话之间锁等待的关系

 

select a.sid holdsid,b.sid waitsid,a.type,a.id1,a.id2,a.ctime from v$lock a,v$lock b

where a.id1=b.id1 and a.id2=b.id2 and a.block=1 and b.block=0;

 

6.查询锁等待事件

select * from v$session_wait where event='enqueue';

7.查找锁住的表和解锁

select b.owner TABLEOWNER, b.object_name TABLENAME, c.OSUSER LOCKBY, c.USERNAME LOGINID, c.sid SID, c.SERIAL# SERIAL
from v$locked_object a,dba_objects b, v$session 
where b.object_id a.object_id AND a.SESSION_ID =c.sid;
--通过SID, SERIAL解锁 
--alter system kill session 'SID, SERIAL';

 

也可以在操作系统层面kill

在OS上杀死这个进程(线程):
1)在unix上,用root身份执行命令:
  #kill -9 #spid(即上面查到的spid)
2)在windows用orakill杀死线程,orakill是oracle提供的一个可执行命令,语法为:
  orakill sid thread
  其中:
  sid:表示要杀死的进程属于的实例名
  thread:是要杀掉的线程号,即上面查到的spid。
  例:c:>orakill orcl #spid

 

8.

select s.username, o.object_name, s.machine, s.sid, s.serial#, k.type,k.LMODE,k.BLOCK

  from v$locked_object l, dba_objects o, v$session s, v$lock k

 where l.object_id = o.object_id

   and l.session_id = s.sid

   and k.sid = s.sid

 

 

几个名词概念
statement: 一个SQL语句。 

session: 一个由ORACLE用户产生的连接,一个用户能产生多个SESSION ,但相互之间是独立的。 

transaction:所有的改动都能划分到transaction里,一个transaction包含一个或多个SQL。当一个SESSION建立的时候就是个TRANSACTION开始的时刻,此后transaction的开始和结束由DCL控制,也就是每个COMMIT/ROLLBACK都标示着一个transaction的结束。 

consistency:是对于statement级别而不是transaction级别来说的。sql statement 得到的数据都是以sql statement开始的IMAGE。 

用法介绍
update, insert ,delete, select ... for update会LOCK相应的ROW 。 
只有一个TRANSACTION可以LOCK相应的行,也就是说如果一个ROW已经LOCKED了,那就不能被其他TRANSACTION所LOCK了。 

LOCK由statement产生但却由TRANSACTION结尾(commit,rollback),也就是说一个SQL完成后LOCK还会存在,只有在COMMIT/ROLLBACK后才会师释放。

简单举例
transaction A下面
select from  connector where a.MOBILE='13937134399' for updata

如上,这个将会对查询出来的行加上一个行锁,如果在
transaction B下面对这一行数据进行增删改都将会等待,普通的查询可以,使用 select for update 查询也需要等待。
需要在transaction A下面执行需要的操作之后commit或者rollback之后,在其他transaction 下面才可以对此表此行进行操作。

使用这个行锁的情况一般是对并发的情况要求比较高的时候,需要锁住某行进行一些更新语句之后进行释放,再让其他transaction 去操作。在这次外呼系统中很好的利用了这点解决了并发的问题。

for update 后面还可以跟着[OF cols] [NOWAIT]
of 的使用主要是针对多表关联的时候,如果不使用of,对两个表涉及到的行都将锁住,使用of可以指定锁定哪个表,
例如:select a.MOBILE,b.NAME from  connector a,student 
where a.STU_ID=b.ID and a.MOBILE='13937134399' for updata of a.MOBILE  
这样的话student表中对应的行是不加锁的,对connector一个表中行加锁
不使用两个表都加锁。
 
[NOWAIT]的使用是当锁冲突的时候提示的情况:
当有LOCK冲突时会提示错误并结束STATEMENT而不是在那里等待.返回错误是"ORA-00054: resource busy and acquire with NOWAIT specified" ,如果不使用就会一直等待,直到锁释放之后执行。
在页面上调试的时候由于异常处理不好,把数据锁住了没有提交,也没有rollback,遇到这样的情况的时候可以通过以下方式解决:

-----查看被锁对象的序列号、sid
SELECT o.owner,o.object_name,o.object_type,s.sid,s.serial# 
FROM v$locked_object l,dba_objects o,v$session 
WHERE l.object_id=o.object_id 
AND l.session_id=s.sid 
ORDER BY o.object_id,xidusn DESC
/
------利用sid 和序列号删除
alter system kill session '243,10265';
243是sid 10265是序列号

所以在使用锁的时候一定要做好页面的异常控制,不然很容易出问题。

*******************************************************
数据库中锁类型的介绍:
有两种基本的锁类型,排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
其中DML锁(data locks,数据锁),用于保护数据的完整性
DML锁的目的在于保证并发情况下的数据完整性,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

在此分享的简单的select  for update应该属于DML锁中的TX锁,属于行级锁

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值