摘要:一旦申請(qǐng)成功,則會(huì)對(duì)將要修改的記錄申請(qǐng)排他鎖,如果此時(shí)其他會(huì)話正在修改該記錄,那么等待其事務(wù)結(jié)束后再為修改的記錄加上排他鎖。該模式下不允許其他的并行會(huì)話對(duì)同一張表使用排他鎖,但允許其利用語(yǔ)句或命令鎖定同一張表中的其他記錄。
本文以oracle數(shù)據(jù)庫(kù)學(xué)習(xí)數(shù)據(jù)庫(kù)鎖 鎖的分類
oracle中分為兩種模式的鎖,一種是排他鎖(X鎖),另一種是共享所(S鎖).
排他鎖,也可以叫寫(xiě)鎖
共享所,也可以叫讀鎖
鎖是實(shí)現(xiàn)并發(fā)的主要手段,在數(shù)據(jù)庫(kù)中應(yīng)用頻繁,但很多都由數(shù)據(jù)庫(kù)自動(dòng)管理,當(dāng)事務(wù)提交后會(huì)自動(dòng)釋放鎖.
鎖的類型Oracle為了使數(shù)據(jù)庫(kù)實(shí)現(xiàn)高度并發(fā)訪問(wèn),它使用了不同類型的鎖來(lái)管理并發(fā)會(huì)話對(duì)數(shù)據(jù)對(duì)象的操作.Oracle的鎖按作用對(duì)象不同分為如下幾種類型.
DML鎖: 該類型的鎖被稱為數(shù)據(jù)鎖,用于保護(hù)數(shù)據(jù)
DDL鎖: 可以保護(hù)模式中對(duì)象的結(jié)構(gòu)
內(nèi)部閂鎖: 保護(hù)數(shù)據(jù)庫(kù)的內(nèi)部結(jié)構(gòu),完全自動(dòng)調(diào)用
這里主要介紹下常用的DML鎖,它主要保證了并發(fā)訪問(wèn)時(shí)數(shù)據(jù)的完整性.它又可以分為以下兩種類型的鎖:
1) 行級(jí)鎖(TX),也可以稱為事務(wù)鎖.當(dāng)修改表中某行記錄時(shí),需要對(duì)將要修改的記錄加行級(jí)鎖,防止兩個(gè)事務(wù)同時(shí)修改相同記錄,事務(wù)結(jié)束,該鎖也會(huì)釋放,是粒度最細(xì)的鎖.該鎖只能屬于排他鎖(X鎖).
2) 表級(jí)鎖(TM),主要作用書(shū)防止在修改表的數(shù)據(jù)時(shí),表的結(jié)構(gòu)發(fā)生變化.例如,會(huì)話S在修改表A的數(shù)據(jù)時(shí),它會(huì)得到表A的TM鎖,而此時(shí)將不允許其他會(huì)話對(duì)該表進(jìn)行變更或刪除操作. 該情況的驗(yàn)證過(guò)程如下:
UPDATE TABLE_NAME SET COLUMN= "test" WHERE ID = "id";
此時(shí)已經(jīng)鎖定該表,表級(jí)鎖將不允許在事務(wù)結(jié)束前其他會(huì)話對(duì)表TABLE_NAME進(jìn)行DDL操作.
其次,在執(zhí)行DROP TABLE TABLE_NAME操作,執(zhí)行后會(huì)提示ORA-00054錯(cuò)誤.
原因是:
在執(zhí)行DML操作時(shí),數(shù)據(jù)庫(kù)會(huì)先申請(qǐng)數(shù)據(jù)對(duì)象上的共享鎖,防止其他會(huì)話對(duì)該對(duì)象執(zhí)行DDL操作。一旦申請(qǐng)成功,則會(huì)對(duì)將要修改的記錄申請(qǐng)排他鎖,如果此時(shí)其他會(huì)話正在修改該記錄,那么等待其事務(wù)結(jié)束后再為修改的記錄加上排他鎖。
ROW SHARE:行級(jí)共享鎖(RS)。該模式下不允許其他的并行會(huì)話對(duì)同一張表使用排他鎖,但允許其利用DML語(yǔ)句或lock命令鎖定同一張表中的其他記錄。SELECT...FROM FOR UPDATE 語(yǔ)句就是給記錄加上了RS鎖.
ROW EXCLUSEIVE, 行級(jí)排他鎖(RX).該模式下允許并行會(huì)話對(duì)同一張表的其他數(shù)據(jù)進(jìn)行修改,但不允許并行會(huì)話對(duì)同一張表使用排他鎖.
SHARE,共享鎖(S).該模式下,不允許會(huì)話更新表,但允許會(huì)話對(duì)表添加RS鎖.
SHARE ROW EXCLUSIVE,共享行級(jí)排他鎖(SRX).該模式下,不能對(duì)同一張表進(jìn)行DML操作,也不能添加S鎖.
EXCLUSIVE,排他鎖(X).該模式下,其他的并行會(huì)話不能對(duì)表進(jìn)行DML和DDL操作,該表只能讀.
下表列出了以上5中模式相互之間的兼容關(guān)系.其中,?表示相互兼容,×表示相互不兼容
RS | S | RX | SRX | X | ||
---|---|---|---|---|---|---|
RS | ? | ? | ? | ? | × | |
S | ? | ? | × | × | × | |
RX | ? | × | ? | ? | × | |
SRX | ? | × | × | × | × | |
X | × | × | × | × | × |
下面所示是Oracle中的各種SQL語(yǔ)句所產(chǎn)生的表級(jí)鎖模式以及允許的鎖定模式情況的匯總.
SQL語(yǔ)句 | 表鎖模式 | RS | S | RX | SRX | X |
---|---|---|---|---|---|---|
SELECT ...FROM table | NONE | Y | Y | Y | Y | Y |
INSERT INTO ... | RX | Y | N | Y | N | N |
UPDATE table ... | RX | Y | N | Y | N | N |
DELETE FROM table ... | RX | Y | N | Y | N | N |
SELECT * FROM table FOR UPDATE | RX | Y | N | Y | N | N |
LOCK TABLE table IN ROW SHARE MODE | RS | Y | Y | Y | Y | N |
LOCK TABLE table IN ROW EXCLUSIVE MODE | RX | Y | N | Y | N | N |
LOCK TABLE table IN SHARE MODE | S | Y | N | N | N | N |
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE | SRX | Y | N | N | N | N |
LOCK TABLE table IN EXCLUSIVE MODE | X | N | N | N | N | N |
在Oracle中除了執(zhí)行DML時(shí)自動(dòng)為表添加TM鎖外,也可以主動(dòng)地為表添加TM鎖,語(yǔ)法如下:
LOCK TABLE [schema.] table IN [EXCLUSIVE] [SHARE] [ROW EXCLUSIVE] [SHARE ROW EXCLUSIVE] [ROW SHARE* | SHARE UPDATE*] MODE [NOWAIT]
DDL鎖也可以稱為數(shù)據(jù)字典鎖,主要作用是保護(hù)模式中對(duì)象的結(jié)構(gòu).當(dāng)執(zhí)行DDL操作時(shí)首先Oracle會(huì)自動(dòng)地隱式提交一次事務(wù),然后自動(dòng)地給處理對(duì)象加上鎖;當(dāng)DDL結(jié)束時(shí),Oracle會(huì)隱式地提交事務(wù)并釋放DDL鎖.與DML不同的是,用戶不能顯式的要求使用DDL鎖.
DDL鎖分為如下3類:
Exclusive DDL Lock,排他DDL鎖定.如果對(duì)象加上了該類型的鎖,那么對(duì)象不能被其他會(huì)話修改,而且該對(duì)象也不能再增加其他類型的DDL鎖.如果是表,此時(shí)可以讀取數(shù)據(jù).
Shared DDL Lock,共享DDL鎖定.保護(hù)對(duì)象的結(jié)構(gòu),其他會(huì)話不能修改該對(duì)象的結(jié)構(gòu),但是允許修改數(shù)據(jù).
Breakable Parsed Lock,能打破的解析鎖定.該類型的鎖可以被打斷,不能禁止DDL操作.
鎖等待與死鎖 鎖等待在某些情況下由于占用的資源不能及時(shí)釋放,而造成鎖等待,也可以叫鎖沖突.鎖等待會(huì)嚴(yán)重地影響數(shù)據(jù)庫(kù)性能和日常工作.
例如當(dāng)一個(gè)會(huì)話修改表A的記錄時(shí),它會(huì)對(duì)該記錄加鎖,而此時(shí)如果另一個(gè)會(huì)話也來(lái)修改此記錄,那么第二個(gè)會(huì)話將因得不到排他鎖而一直等待,此時(shí)會(huì)出現(xiàn)執(zhí)行SQL時(shí)數(shù)據(jù)庫(kù)長(zhǎng)時(shí)間沒(méi)有響應(yīng)的現(xiàn)象.直到第一個(gè)會(huì)話把事務(wù)提交,釋放鎖,第二個(gè)會(huì)話才能對(duì)數(shù)據(jù)進(jìn)行操作.
下面為大家示例鎖等待現(xiàn)象:
打開(kāi)SLQ*PLUS窗口,修改PRODUCTINFO 表中PRODUCTID 字段為1的記錄,腳本如下:
UPDATE PRODUCTINFO SET ORIGIN = "修改1" WHERE PRODUCTID = 1;
此時(shí)雖然提示已更新,但事務(wù)并沒(méi)有提交.接下來(lái)進(jìn)行第二步操作.
打開(kāi)另一個(gè)SQL*PLUS 窗口,同樣修改PRODUCTINFO 表中PRODUCTID字段為1的記錄,腳本如下:
UPDATE PRODUCTINFO SET ORIGIN = "修改2" WHERE PRODUCTID = 1;
此時(shí)執(zhí)行效果不會(huì)提示已更新,而是一直等待.
此時(shí)的情況是因?yàn)榈谝粋€(gè)會(huì)話封鎖了該記錄,但事務(wù)沒(méi)有結(jié)束,鎖不會(huì)釋放,而這時(shí)第二個(gè)會(huì)話也要修改同一條記錄,但它缺沒(méi)有辦法獲得排他鎖,所以只能等待.如果第一個(gè)會(huì)話修改數(shù)據(jù)的事務(wù)結(jié)束,那么第二個(gè)會(huì)話會(huì)結(jié)束等待.及時(shí)地結(jié)束事務(wù)是解決鎖等待情況發(fā)生的有效方法.
死鎖死鎖的發(fā)生和鎖等待不同,它是鎖等待的一個(gè)特例,通常發(fā)生在兩個(gè)或者多個(gè)會(huì)話之間.假設(shè)一個(gè)會(huì)話想要修改兩個(gè)資源對(duì)象,可以是表也可以是字段,修改這兩個(gè)資源的操作在一個(gè)事務(wù)當(dāng)中,當(dāng)它修改第一個(gè)對(duì)象時(shí)需要對(duì)其鎖定,然后等待第二個(gè)對(duì)象,這時(shí)如果另外一個(gè)會(huì)話也需要修改這兩個(gè)資源對(duì)象,并且已經(jīng)獲得對(duì)第二個(gè)對(duì)象的鎖定,那么就會(huì)出現(xiàn)死鎖,因?yàn)楫?dāng)前會(huì)話鎖定了第一個(gè)對(duì)象等待第二個(gè)對(duì)象,而另一個(gè)會(huì)話鎖定了第二個(gè)對(duì)象等待第一個(gè)對(duì)象.這樣,兩個(gè)會(huì)話都不能得到想要得到的對(duì)象,于是出現(xiàn)死鎖.
這里例子就不在展示,大家可以自行試一試.實(shí)際開(kāi)發(fā)中出現(xiàn)死鎖情況大致有以下幾種原因:
用戶沒(méi)有良好的編程習(xí)慣,偶爾會(huì)忘記提交事務(wù),導(dǎo)致長(zhǎng)時(shí)間占用資源.
操作的記錄過(guò)多,而且操作過(guò)程中沒(méi)有良好地對(duì)其分組.對(duì)于數(shù)據(jù)兩很大的操作,可以將其分成幾組提交事務(wù),這樣可以避免長(zhǎng)時(shí)間的占用資源.
邏輯錯(cuò)誤,兩個(gè)會(huì)話都想得到已占有的資源.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/17733.html
摘要:前情提要深入理解內(nèi)存模型四鎖的釋放獲取建立的關(guān)系鎖是并發(fā)編程中最重要的同步機(jī)制。鎖內(nèi)存語(yǔ)義的實(shí)現(xiàn)本文將借助的源代碼,來(lái)分析鎖內(nèi)存語(yǔ)義的具體實(shí)現(xiàn)機(jī)制。請(qǐng)看下篇深入理解內(nèi)存模型六 前情提要 深入理解Java內(nèi)存模型(四)—— volatile 鎖的釋放-獲取建立的happens before 關(guān)系 鎖是java并發(fā)編程中最重要的同步機(jī)制。鎖除了讓臨界區(qū)互斥執(zhí)行外,還可以讓釋放鎖的線程向...
摘要:公平鎖為了保證時(shí)間上的絕對(duì)順序,需要頻繁的上下文切換,而非公平鎖會(huì)降低一定的上下文切換,降低性能開(kāi)銷。因此,默認(rèn)選擇的是非公平鎖,則是為了減少一部分上下文切換,保證了系統(tǒng)更大的吞吐量。ReentrantLock簡(jiǎn)介ReentrantLock重入鎖,是實(shí)現(xiàn)Lock接口的一個(gè)類,也是在實(shí)際編程中使用頻率很高的一個(gè)鎖, 支持重入性,表示能夠?qū)蚕碣Y源能夠重復(fù)加鎖,即當(dāng)前線程獲取該鎖再次獲取不會(huì)被阻...
閱讀 1401·2019-08-30 12:54
閱讀 1883·2019-08-30 11:16
閱讀 1628·2019-08-30 10:50
閱讀 2462·2019-08-29 16:17
閱讀 1282·2019-08-26 12:17
閱讀 1391·2019-08-26 10:15
閱讀 2399·2019-08-23 18:38
閱讀 797·2019-08-23 17:50