溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

ORACLE鎖的機(jī)制介紹

發(fā)布時(shí)間:2021-08-25 16:30:07 來源:億速云 閱讀:143 作者:chen 欄目:關(guān)系型數(shù)據(jù)庫

這篇文章主要講解了“ORACLE鎖的機(jī)制介紹”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“ORACLE鎖的機(jī)制介紹”吧!



數(shù)據(jù)庫是一個(gè)多用戶使用的共享資源。當(dāng)多個(gè)用戶并發(fā)地存取數(shù)據(jù)時(shí),在數(shù)據(jù)庫中就會(huì)產(chǎn)生多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)的情況。若對并發(fā)操作不加控制就可能會(huì)讀取和存儲(chǔ)不正確的數(shù)據(jù),破壞數(shù)據(jù)庫的一致性。 

加鎖是實(shí)現(xiàn)數(shù)據(jù)庫并發(fā)控制的一個(gè)非常重要的技術(shù)。當(dāng)事務(wù)在對某個(gè)數(shù)據(jù)對象進(jìn)行操作前,先向系統(tǒng)發(fā)出請求,對其加鎖。加鎖后事務(wù)就對該數(shù)據(jù)對象有了一定的控制,在該事務(wù)釋放鎖之前,其他的事務(wù)不能對此數(shù)據(jù)對象進(jìn)行更新操作。 

在數(shù)據(jù)庫中有兩種基本的鎖類型:排它鎖(Exclusive Locks,即X鎖)和共享鎖(Share Locks,即S鎖)。當(dāng)數(shù)據(jù)對象被加上排它鎖時(shí),其他的事務(wù)不能對它讀取和修改。加了共享鎖的數(shù)據(jù)對象可以被其他事務(wù)讀取,但不能修改。數(shù)據(jù)庫利用這兩種基本的鎖類型來對數(shù)據(jù)庫的事務(wù)進(jìn)行并發(fā)控制。 

Oracle數(shù)據(jù)庫的鎖類型 

根據(jù)保護(hù)的對象不同,Oracle數(shù)據(jù)庫鎖可以分為以下幾大類:DML鎖(data locks,數(shù)據(jù)鎖),用于保護(hù)數(shù)據(jù)的完整性;DDL鎖(dictionary locks,字典鎖),用于保護(hù)數(shù)據(jù)庫對象的結(jié)構(gòu),如表、索引等的結(jié)構(gòu)定義;內(nèi)部鎖和閂(internal locks and latches),保護(hù) 數(shù)據(jù)庫的內(nèi)部結(jié)構(gòu)。 

DML鎖的目的在于保證并發(fā)情況下的數(shù)據(jù)完整性。在Oracle數(shù)據(jù)庫中,DML鎖主要包括TM鎖和TX鎖,其中TM鎖稱為表級鎖,TX鎖稱為事務(wù)鎖或行級鎖。 

當(dāng)Oracle執(zhí)行DML語句時(shí),系統(tǒng)自動(dòng)在所要操作的表上申請TM類型的鎖。當(dāng)TM鎖獲得后,系統(tǒng)再自動(dòng)申請TX類型的鎖,并將實(shí)際鎖定的數(shù)據(jù)行的鎖標(biāo)志位進(jìn)行置位。這樣在事務(wù)加鎖前檢查TX鎖相容性時(shí)就不用再逐行檢查鎖標(biāo)志,而只需檢查TM鎖模式的相容性即可,大大提高了系統(tǒng)的效率。TM鎖包括了SS、SX、S、X 等多種模式,在數(shù)據(jù)庫中用0-6來表示。不同的SQL操作產(chǎn)生不同類型的TM鎖。 

在數(shù)據(jù)行上只有X鎖(排他鎖)。在Oracle數(shù)據(jù)庫中,當(dāng)一個(gè)事務(wù)首次發(fā)起一個(gè)DML語句時(shí)就獲得一個(gè)TX鎖,該鎖保持到事務(wù)被提交或回滾。當(dāng)兩個(gè)或多個(gè)會(huì)話在表的同一條記錄上執(zhí)行 DML語句時(shí),第一個(gè)會(huì)話在該條記錄上加鎖,其他的會(huì)話處于等待狀態(tài)。當(dāng)?shù)谝粋€(gè)會(huì)話提交后,TX鎖被釋放,其他會(huì)話才可以加鎖。 

當(dāng)Oracle數(shù)據(jù)庫發(fā)生TX鎖等待時(shí),如果不及時(shí)處理常常會(huì)引起Oracle數(shù)據(jù)庫掛起,或?qū)е滤梨i的發(fā)生,產(chǎn)生ORA-60的錯(cuò)誤。這些現(xiàn)象都會(huì)對實(shí)際應(yīng)用產(chǎn)生極大的危害,如長時(shí)間未響應(yīng),大量事務(wù)失敗等。 

一、悲觀封鎖 
鎖在用戶修改之前就發(fā)揮作用: 
Select ..for update(nowait) 
Select * from tab1 for update 
用戶發(fā)出這條命令之后,oracle將會(huì)對返回集中的數(shù)據(jù)建立行級封鎖,以防止其他用戶的修改。 
如果此時(shí)其他用戶對上面返回結(jié)果集的數(shù)據(jù)進(jìn)行dml或ddl操作都會(huì)返回一個(gè)錯(cuò)誤信息或發(fā)生阻塞。 

1:對返回結(jié)果集進(jìn)行update或delete操作會(huì)發(fā)生阻塞。 
2:對該表進(jìn)行ddl操作將會(huì)報(bào):Ora-00054:resource busy and acquire with nowait specified. 

原因分析 
此時(shí)Oracle已經(jīng)對返回的結(jié)果集上加了排它的行級鎖,所有其他對這些數(shù)據(jù)進(jìn)行的修改或刪除操作都必須等待這個(gè)鎖的釋放,產(chǎn)生的外在現(xiàn)象就是其他的操作將發(fā)生阻塞,這個(gè)操作commit或rollback. 
同樣這個(gè)查詢的事務(wù)將會(huì)對該表加表級鎖,不允許對該表的任何ddl操作,否則將會(huì)報(bào)出ora-00054錯(cuò)誤::resource busy and acquire with nowait specified. 

二、樂觀封鎖
樂觀的認(rèn)為數(shù)據(jù)在select出來到update進(jìn)取并提交的這段時(shí)間數(shù)據(jù)不會(huì)被更改。這里面有一種潛在的危險(xiǎn)就是由于被選出的結(jié)果集并沒有被鎖定,是存在一種可能被其他用戶更改的可能。因此Oracle仍然建議是用悲觀封鎖,因?yàn)檫@樣會(huì)更安全。 

阻塞:
當(dāng)一個(gè)會(huì)話保持另一個(gè)會(huì)話正在請求的資源上的鎖定時(shí),就會(huì)發(fā)生阻塞。被阻塞的會(huì)話將一直掛起,直到持有鎖的會(huì)話放棄鎖定的資源為止。4個(gè)常見的dml語句會(huì)產(chǎn)生阻塞 
INSERT 
UPDATE 
DELETE 
SELECT…FOR UPDATE 

INSERT:
Insert發(fā)生阻塞的唯一情況就是用戶擁有一個(gè)建有主鍵約束的表。當(dāng)2個(gè)的會(huì)話同時(shí)試圖向表中插入相同的數(shù)據(jù)時(shí),其中的一個(gè)會(huì)話將被阻塞,直到另外一個(gè)會(huì)話提交或會(huì)滾。一個(gè)會(huì)話提交時(shí),另一個(gè)會(huì)話將收到主鍵重復(fù)的錯(cuò)誤?;貪L時(shí),被阻塞的會(huì)話將繼續(xù)執(zhí)行。 

UPDATE 和DELETE當(dāng)執(zhí)行Update和delete操作的數(shù)據(jù)行已經(jīng)被另外的會(huì)話鎖定時(shí),將會(huì)發(fā)生阻塞,直到另一個(gè)會(huì)話提交或會(huì)滾。 

Select …for update 
當(dāng)一個(gè)用戶發(fā)出select..for update的操作準(zhǔn)備對返回的結(jié)果集進(jìn)行修改時(shí),如果結(jié)果集已經(jīng)被另一個(gè)會(huì)話鎖定,就是發(fā)生阻塞。需要等另一個(gè)會(huì)話結(jié)束之后才可繼續(xù)執(zhí)行??梢酝ㄟ^發(fā)出 select… for update nowait的語句來避免發(fā)生阻塞,如果資源已經(jīng)被另一個(gè)會(huì)話鎖定,則會(huì)返回以下錯(cuò)誤:Ora-00054:resource busy and acquire with nowait specified. 


三、死鎖-deadlock 
定義:當(dāng)兩個(gè)用戶希望持有對方的資源時(shí)就會(huì)發(fā)生死鎖. 
即兩個(gè)用戶互相等待對方釋放資源時(shí),oracle認(rèn)定為產(chǎn)生了死鎖,在這種情況下,將以犧牲一個(gè)用戶作為代價(jià),另一個(gè)用戶繼續(xù)執(zhí)行,犧牲的用戶的事務(wù)將回滾. 
例子: 
1:用戶1對A表進(jìn)行Update,沒有提交。 
2:用戶2對B表進(jìn)行Update,沒有提交。 
此時(shí)雙反不存在資源共享的問題。 
3:如果用戶2此時(shí)對A表作update,則會(huì)發(fā)生阻塞,需要等到用戶一的事物結(jié)束。 
4:如果此時(shí)用戶1又對B表作update,則產(chǎn)生死鎖。此時(shí)Oracle會(huì)選擇其中一個(gè)用戶進(jìn)行會(huì)滾,使另一個(gè)用戶繼續(xù)執(zhí)行操作。 

起因:
Oracle的死鎖問題實(shí)際上很少見,如果發(fā)生,基本上都是不正確的程序設(shè)計(jì)造成的,經(jīng)過調(diào)整后,基本上都會(huì)避免死鎖的發(fā)生。 

四、DML鎖分類表 

五、oracle 鎖問題的解決

1. 查看哪些session鎖: 
SQL語句:
select 'alter system kill session ''' || sid || ',' || serial# || ''';'
  from v$session
 where sid in (select sid from v$lock where block = 1);


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;


3. kill鎖的進(jìn)程. 
SQL語句:alter system kill session 'sid,serial#' immediate;

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;

注: 
> : 重定向輸出,將文件的標(biāo)準(zhǔn)輸出重新定向輸出到文件,或?qū)?shù)據(jù)文件作為另一程序的標(biāo)準(zhǔn)輸入內(nèi)容。 
| :UNIX管道:將一文件的輸出作為另一文件的輸入. 

感謝各位的閱讀,以上就是“ORACLE鎖的機(jī)制介紹”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對ORACLE鎖的機(jī)制介紹這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI