根據保護的數據不同,ORACLE的數據庫鎖分為以下幾大類:
1.DML鎖(data locks數據鎖),用於保護數據的完整性;
2.DDL鎖(dictionary locks字典鎖),用於保護數據庫對象的結構,例如表、索引的結構定義;
3.內部鎖或閂(internal locks or latches),用於保護內部結構
在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的錯誤。這些現象都會對實際應用產生極大的危害,如長時間未響應,大量事務失敗等。
ORACLE里鎖有以下幾種模式:
0:none
1:null 空
2:Row-S 行共享(RS):共享表鎖,sub share
3:Row-X 行獨占(RX):用於行的修改,sub exclusive
4:Share 共享鎖(S):阻止其他DML操作,share
5:S/Row-X 共享行獨占(SRX):阻止其他事務操作,share/sub exclusive
6:exclusive 獨占(X):獨立訪問使用,exclusive
我們可以從這個表找出至少2個東西,.第一是每種數據庫操作都對應的是什么樣的鎖,第二是每種鎖之間,如果遇到之后是否會產生沖突,所謂沖突就是是否會使當前的數據庫操作夯住.如果兩個操作鎖定的是同一行,那么就會有沖突,后操作的會等待前一個操作完成之后再完成,否則會一直夯在那兒;如果不為同一行,那么則不會沖突,后操作的不會等待.舉一個例子來說明:假設現在A操作為:對id=1的記錄進行update,而B操作為:對id=2的記錄進行刪除,根據表格說明,在A上操作時在TM級別的鎖會是RX,TX級別只有一個是X,在B上會有一個TM級別的鎖會是RX,TX級別只有一個X,而根據表格說明,當RX遇到RX的時候,如果2個操作非同一條記錄,那么則不會沖突,故AB兩個操作均會按照各自的先加一個TM鎖,再加一個TX鎖,再順利執行各自的操作,不會夯住。如果將B操作的記錄id換位1,那么兩個操作記錄為同一條記錄,在TM鎖上會表現出沖突,所以B操作就會等待A操作完成提交后(也就是A的TX鎖釋放了后),B再相應的生成一個TX鎖和一個TM鎖再完成操作,否則的話會一直夯住,等待A釋放TX鎖.
create table CHGRANT_20170327 as select * from CHGRANT;
update CHGRANT_20170327 set UPDATETIME='' where operno='HANA0026' and options='1' and changeid='47';
select * from v$lock where type in ('TX');
結果如下:
執行UPDATE語句但不提交:
update CHGRANT_20170327 set UPDATETIME='' where operno='HANA0026' and options='1' and changeid='47';
再看一遍TX鎖的情況,結果為:
明顯多了一個SID為867的鎖,查看SID為867的所有的鎖:
select * from v$lock where sid in ('867');
結果為:
該結果與兩個表的數據對應:
1.取TM鎖的ID1,查詢dba_objects表:
select * from dba_objects where object_id='3824866';
結果:
2.取TX鎖的ADDR,查詢v$transaction表:
select * from v$transaction;
結果:
另開窗口進行delete操作,事務會這被阻塞:
delete from CHGRANT_20170327 where operno='HANA0026' and options='1' and changeid='47';
再次查看TX鎖:
select * from v$lock where type in ('TX');
結果:
又多出了一個SID為875的鎖,查看SID為875的所有鎖:
select * from v$lock where sid in ('875');
結果:
再返回查看這兩個新鎖(SID為867和875)的v$lock情況:
select * from v$lock where sid in ('867','875');
結果:
注意SID為867(即update那個操作)的BLOCK變為了'1'。
現在ROLLBACK那個update操作(867),查看v$lock:
select * from v$lock where sid in ('867','875');
結果:
可見867的鎖記錄已經被釋放掉了。
此時另一窗口的delete操作終於返回了,現在也rollback它。
select * from v$lock where sid in ('867','875');
結果:
兩個事務的鎖都被釋放了。
最后補充一個操作,創建索引的時候會生成的鎖操作:
創建索引的同時,查詢v$lock表
可以發現在創建索引的會生成2個TM鎖,鎖類別分別為4和3,我們查詢這2個TM分別鎖定的是什么對象:
根據查詢結果發現lmode=4的object_id為55160的對象對應的是TTT這個表,LMODE=4對應的是TM的S鎖
原文章地址:
http://blog.csdn.net/vertual/article/details/34540555
http://blog.sina.com.cn/s/blog_95b5eb8c0101i22x.html