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