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 c 
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 a 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 b 
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 s 
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鎖,屬於行級鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章